<template>
  <div class="main">
    <div id="governmentMap"></div>
    <!-- 导航按钮 -->
    <div class="toolBox">
      <div
        class="toolItem"
        :class="selectNav == 'historical' ? 'active-box' : 'normal-box'"
        @click="changeNav('historical')">
        历史回放
      </div>
      <!-- <div
        class="toolItem"
        :class="selectNav == 'defense' ? 'active-box' : 'normal-box'"
        @click="changeNav('defense')">
        <span>布防管理</span>
        <div class="defense-list" v-if="defenseShow"> -->
      <!-- <div
            class="defense-item"
            :class="defenseIndex == 1 ? 'active-defense' : ''"
            @click.stop="selectDefense(1)">
            设备管理
          </div> -->
      <!-- <div
            class="defense-item"
            :class="defenseIndex == 2 ? 'active-defense' : ''"
            @click.stop="selectDefense(2)">
            保障范围管理
          </div> -->
      <!-- </div>
      </div> -->
      <div
        class="toolItem"
        :class="selectNav == 'white-list' ? 'active-box' : 'normal-box'"
        @click="changeNav('white-list')">
        白名单管理
      </div>
    </div>
    <div class="home-right">
      <!-- 统计数据 -->
      <Statisticaldata />
      <!-- 实时告警 -->
      <realTime @getRealTimeList="getRealTimeList" @histComdetect="hist_comdetect" ref="realtime">
        <!-- 实时告警 插槽 -->
        <template v-slot:real-time-slot>
          <!-- 实时告警列表 -->
          <div class="real-time-box">
            <ul class="real-list" v-if="realtimeList.length !== 0">
              <li
                v-for="(item, index) in realtimeList"
                :key="index"
                class="real-list-item1"
                :class="[
                  droneActiveId ==
                  item.code + item.batchNum + dayjs(item.takeoffTime).format('YYYY-MM-DD HH:mm:ss')
                    ? 'active'
                    : '',
                ]">
                <div
                  class="info"
                  :class="[
                    item.defenseType == 3 ? 'red' : item.defenseType == 2 ? 'orange' : 'blue',
                  ]">
                  <div class="info-top">
                    <span class="time">{{
                      dayjs(item.takeoffTime).format('YYYY-MM-DD HH:mm:ss')
                    }}</span>
                    <span class="model" :title="item.model">{{ item.model }}</span>

                    <span v-if="item.type != 3 && item.type != 2 && item.type != 4"></span>
                    <img
                      v-if="item.type == 1"
                      src="/img/icon-command-real-time-T.png"
                      title="无线频谱定位"
                      alt="无线频谱定位" />
                    <img
                      v-if="item.type == 3 && item.policeDrone != 1"
                      src="/img/icon-drone-whiteFly.png" />
                    <img
                      v-if="item.type == 3 && item.policeDrone == 1"
                      src="/img/icon-drone-police.png" />
                    <img v-if="item.type == 2" src="/img/icon-equipment-AOA.png" />
                    <img v-if="item.type == 4" src="/img/icon-drone-trade.png" />
                    <!-- 是否是 协议破解 侦测到的无人机 -->
                    <img v-if="item.type == 5" src="/img/icon-command-real-time-C.png" />
                    <img v-if="item.type == 7" src="/img/icon-drone-minghang.png" />
                  </div>
                  <!-- <div class="info-bottom" :title="item.discoveryPlace"> -->
                  <div class="info-bottom" :title="item.discoveryPlace">
                    {{ item.discoveryPlace }}发现{{ item.type == 7 ? item.batchNum : ''
                    }}{{ item.model }}{{ item.type == 7 ? '' : '无人机' }}
                  </div>
                  <i class="info-detail-icon" @click="showDroneDetail(item, 1)"></i>
                  <!-- v-if="item.type != 7" -->
                </div>
                <i class="active-icon"></i>
              </li>
            </ul>
            <ul class="real-list">
              <li
                v-for="(item, index) in hisroryList"
                :key="index"
                class="real-list-item"
                :class="{
                  active:
                    droneActiveId ==
                    item.code +
                      item.batchNo +
                      dayjs(item.takeoffTime).format('YYYY-MM-DD HH:mm:ss'),
                }">
                <div class="info gray">
                  <div class="info-top">
                    <span class="time">{{
                      dayjs(item.takeoffTime).format('YYYY-MM-DD HH:mm:ss')
                    }}</span>
                    <span class="model" :title="item.model">{{ item.model }}</span>
                    <span v-if="item.type != 3 && item.type != 2 && item.type != 4"></span>
                    <!-- 是否是 TDOA 设备侦测到的无人机 -->
                    <img
                      v-if="item.type == 1"
                      src="/img/icon-command-real-time-T.png"
                      title="无线频谱定位"
                      alt="无线频谱定位" />
                    <img
                      v-if="item.type == 3 && item.policeDrone != 1"
                      src="/img/icon-drone-whiteFly.png" />
                    <!-- 是否是 协议破解 侦测到的无人机 -->
                    <img v-if="item.type == 5" src="/img/icon-command-real-time-C.png" />
                    <img
                      v-if="item.type == 3 && item.policeDrone == 1"
                      src="/img/icon-drone-police.png" />
                    <img v-if="item.type == 2" src="/img/icon-equipment-AOA.png" />
                    <img v-if="item.type == 4" src="/img/icon-drone-trade.png" />
                    <img v-if="item.type == 7" src="/img/icon-drone-minghang.png" />
                  </div>
                  <!-- <div class="info-bottom" :title="item.discoveryPlace"> -->
                  <div class="info-bottom" :title="item.discoveryPlace">
                    {{ item.discoveryPlace }}发现{{ item.model
                    }}{{ item.type == 7 ? '' : '无人机' }}
                  </div>
                  <i class="info-detail-icon" @click="historydata(item)"></i>
                </div>
                <i class="active-icon"></i>
              </li>
            </ul>
            <div class="empty" v-if="realtimeList.length == 0 && hisroryList.length == 0">
              暂无数据
            </div>
          </div>
          <!-- 遮罩 -->
          <div class="real-time-box-overlay"></div>
        </template>
      </realTime>
      <!-- 反制设备 -->
      <Counterequipment ref="counterequipment" @Jumpdevicedialog="Jumpdevicedialog" />
    </div>
    <!-- 历史回放弹窗 -->
    <History v-if="historyShow" @closeHistory="closeNav" @historydata="historydata" />
    <!-- 设备弹窗 -->
    <Devicedialog
      v-if="showdevicedialog"
      title="设备管理"
      :width="475"
      :height="460"
      :deviceList="deviceList"
      @closeDialog="closeNav">
    </Devicedialog>
    <!-- 保障范围管理 -->
    <CoverageManagement
      v-if="defenseShow"
      title="保障范围管理"
      @getDenfensInfo="getDenfensInfo"
      @closeDialog="closeNav"
      @enableTool="enableTool">
    </CoverageManagement>
    <!-- 白名单弹窗 -->
    <Whitelistdialog
      v-if="showwhitelistdialog"
      title="白名单管理"
      width="500"
      @closeDialog="closeNav"
      @enableTool="enableTool">
    </Whitelistdialog>
    <!-- 无人机轨迹信息   right: menu == '4' ? '-7.99%' : rightBoxState === 'an' ? '43%' : '18%',     54% -->
    <div class="detail-box" v-show="showDronePopup === 'droneDetail'">
      <uavTrajectory
        v-if="showDronePopup === 'droneDetail'"
        :detailList="droneInfo"
        :suspectedInfo="suspectedInfo"
        @offDroneDetail="offDroneDetail" />
    </div>
    <!-- 设备信息弹窗 -->
    <deviceDetails
      ref="deviceDetail"
      v-show="showdeviceDetail"
      :deviceDetailList="deviceInfo"
      @showDeviceInfo="showDeviceInfo"
      @changeDisposal="changeDisposal"
      @close-equipment-counter="closeEquipmentCounter"
      @cancelMarker="cancelMarker"></deviceDetails>
  </div>
</template>
<script>
  export default {
    name: 'MianMap',
  }
</script>

<script setup>
  import {
    onMounted,
    ref,
    provide,
    onUnmounted,
    defineAsyncComponent,
    watch,
    computed,
    nextTick,
  } from 'vue'
  import {
    comdetect,
    hisDroneDirect,
    comdetail,
    hisDroneCoors,
    getDeviceLoc,
    getDeviceInfo,
    getdeviceAngle,
    getcallDevice,
  } from '@/api/home.js'
  import { require } from '@/utils/require.js'
  import dayjs from 'dayjs/esm/index.js'
  import * as THREE from 'three'
  import modifyMap from '@/utils/filterColor.js' // 地图调色
  import Statisticaldata from '@/components/home/statisticaldata.vue'
  import realTime from '@/components/home/realTime.vue'
  import Counterequipment from '@/components/home/counterequipment.vue'
  import Devicedialog from '@/components/home/dialog/devicedialog.vue'
  import CoverageManagement from '@/components/home/dialog/coverageManagement.vue'
  import Whitelistdialog from '@/components/home/dialog/whitelistdialog.vue'
  import uavTrajectory from '@/components/home/dialog/uav_trajectory.vue'
  import History from '@/components/home/history.vue'
  import { ElMessage } from 'element-plus'
  import EllipsoidFadeMaterialProperty from '@/utils/EllipsoidFadeMaterialProperty.js'
  import { useDroneStore } from '@/stores/mqttInfo'
  import { getDefense } from '@/api/defens.js'
  import { getDeviceList } from '@/api/home.js'
  import CircleRippleMaterialProperty from '@/utils/CircleRippleMaterialProperty.js'
  import { gcj02towgs84 } from '@/utils/coordTransform.js'

  const deviceDetails = defineAsyncComponent(() =>
    import('@/components/home/dialog/device_details.vue')
  )
  const droneStore = useDroneStore()
  const selectNav = ref('') //选中的导航按钮value
  const historyShow = ref(false) //历史回放列表visible
  const realtimeList = ref([]) // 实时侦测数据
  const hisroryList = ref([]) //历史数据
  const defenseShow = ref(false)
  const defenseIndex = ref(0)
  const deviceDetail = ref(null) //设备详情弹窗

  let showdevicedialog = ref(false) //设备管理弹窗
  let showwhitelistdialog = ref(false) // 白名单弹窗
  let coverageShow = ref(false) // 保障范围管理弹窗
  let showdeviceDetail = ref(false)
  let DraworientationIntval = null //定向设备的扇形

  //地图变量
  let suspectedInfo = ref({}) //根据序列号查询飞手信息

  //ref
  let realtime = ref() //实时侦测ref应用
  let counterequipment = ref() //反制列表ref应用

  //地图
  let aMap = null
  //经纬度
  let viewer = null

  const droneDatestate = computed(() => droneStore.droneDatestate)
  const droneGroupstate = computed(() => droneStore.droneGroupstate)
  watch(
    droneStore.droneDatestate,
    (val) => {
      let type = droneDatestate.value.droneDate.split('=')[1] // 2:无人机降落
      let info = droneDatestate.value.droneDate.split('=')[0]

      let flydata = info.trim()
      // console.log('flydata', flydata)

      if (flydata != '') {
        if (type == 2) {
          console.log(
            '无人机降落》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》'
          )
          // let num = droneStore.droneDatestate.droneDate.split('-')[0]
          let num = JSON.parse(droneStore.droneDatestate.droneDate.split('=')[0]).data.split('-')[0]
          // console.log('num', num)
          let newList = []
          // console.log('realtimeList.value', realtimeList.value)
          realtimeList.value.map((item) => {
            if (item.droneCode != num) {
              newList.push(item)
            } else {
              //历史列表开头添加一条
              if (item.type != 7) {
                hisroryList.value.unshift(item)
              }
            }
          })
          // 无人机降落 更新数据
          realtimeList.value = newList
          //筛选数据
          if (realtime.value.dataType == 'all') {
          } else if (realtime.value.dataType == 'direction') {
            newList = realtimeList.value.filter((jtem) => {
              return jtem.type == 1
            })
          } else if (realtime.value.dataType == 'positioning') {
            newList = realtimeList.value.filter((jtem) => {
              return jtem.type == 2
            })
          } else if (realtime.value.dataType == 'decoding') {
            newList = realtimeList.value.filter((jtem) => {
              return jtem.type == 4
            })
          } else if (realtime.value.dataType == 'minghang') {
            newList = realtimeList.value.filter((jtem) => {
              return jtem.type == 7
            })
          }
          droneStore.setDroneGroup(newList)
          // setTimeout(() => {
          //   getRealTimeList()
          // }, 500)
          drawRealTime(droneGroupstate.value.droneGroupList)
          setTimeout(() => {
            var num = flydata.split('-')[0]
            if (drawState == num) {
              offDroneDetail()
            }
          })
        } else if (type == 1) {
          // type == 1 无人机轨迹数据
          nowflyData(info)
          if (showTrajectory == 0) {
            drawRealTime(droneGroupstate.value.droneGroupList)
          } else {
            let currentFlyData = JSON.parse(flydata)
            if (currentFlyData.data) {
              currentFlyData = JSON.parse(currentFlyData.data)
            }
            //在飞轨迹
            if (drawState == currentFlyData.droneCode) {
              drawRealTimeRajectory(drawState, null, currentFlyData, 1)
            }
          }
        }
      }
    },
    {
      deep: true,
    }
  )
  /**
   * @description: 初始化地图
   */
  const initMap = () => {
    viewer = new Cesium.Viewer('governmentMap', {
      homeButton: false,
      sceneModePicker: false,
      baseLayerPicker: false, // 影像切换
      animation: false, // 是否显示动画控件
      infoBox: false, // 是否显示点击要素之后显示的信息
      selectionIndicator: false, // 要素选中框
      geocoder: false, // 是否显示地名查找控件
      timeline: false, // 必须为true显示时间线组件（如不想显示可以使用样式层叠表修改display：none） 否则viewer.timeline.zoomTo会报undefined错误
      fullscreenButton: false,
      navigationHelpButton: false, // 是否显示帮助信息控件
      shouldAnimate: true, // 必须为true开启动画 否则不会达到飞机模型飞行动画效果
    })
    window.viewer = viewer
    viewer.scene.globe.baseColor = Cesium.Color.fromCssColorString('rgba(49, 108, 140, 0.1)') //设置地球颜色
    viewer.scene.skyAtmosphere.show = false // 隐藏大气，不隐藏的话周围会有一圈光晕
    viewer._cesiumWidget._creditContainer.style.display = 'none' // 去除logo
    viewer.imageryLayers.removeAll(true) // 移除所有图层并销毁

    //是否开启抗锯齿
    viewer.scene.fxaa = true
    viewer.scene.postProcessStages.fxaa.enabled = true

    // 初始化加载海宁矢量地图(本地)
    changBaseMap('haiNingVector')
    // 地图调色
    changeMapColor()

    // 初始化加载海宁卫星地图(车载平台)，反制车上是卫星地图，不需要调色
    // changVehicleMap('satellite')
    // changRoadNetwork('overlay_s')

    /* 设置相机位置-海宁 */
    defaultAngle()

    // 限制地图的缩放大小
    viewer.scene.screenSpaceCameraController.minimumZoomDistance = 500
    // 最大缩放高度（米）
    // 27800
    viewer.scene.screenSpaceCameraController.maximumZoomDistance = 100000

    //  延迟加载白膜
    setTimeout(() => {
      // add3DTiles()
    }, 2000)
  }

  /**
   * @切换瓦片地图（车载）
   */
  const changVehicleMap = (layer) => {
    // 定义本地瓦片底图的URL
    var localTilesetUrl = `/mapApi/${layer}/{z}/{x}/{y}.png`
    // 创建ImageryProvider
    var localTileProvider = new Cesium.UrlTemplateImageryProvider({
      url: localTilesetUrl,
    })

    // 创建ImageryLayer并添加到Viewer中
    viewer.imageryLayers.addImageryProvider(localTileProvider)
  }
  /**
   * @卫星地图路网
   */
  const changRoadNetwork = (layer) => {
    var localTilesetUrl = `/mapApi/${layer}/{z}/{x}/{y}.png`
    // 创建ImageryProvider
    var localTileProvider = new Cesium.UrlTemplateImageryProvider({
      url: localTilesetUrl,
    })

    // 创建ImageryLayer并添加到Viewer中
    viewer.imageryLayers.addImageryProvider(localTileProvider)
  }

  /**
   * @地图调色
   */
  const changeMapColor = (type = 1) => {
    if (type === 1) {
      //   /* 地图调色 */
      modifyMap(
        window.viewer,
        {
          //反色?
          invertColor: true, //反色
          // filterRGB: [10, 49, 85], //过滤器rgb
          filterRGB: [0, 52, 68], //过滤器rgb
          brightness: 0.55, //亮度，值0=1，小于1会减少亮度，大于1会增加亮度
          contrast: 2.58, //对比度，值0=1，小于1会减少对比度、亮度，大于1会增加对比度、亮度
          gamma: 0.1, //值0=1，小于1会增加对比度，大于1会减少对比度
          hue: 0, //颜色，值能为0，可以为正负数，接近0为原始颜色，改变饱和度，轻微改变色相
          saturation: 0.1, //饱和度+色相，值不能为0，可以为正负数，接近0为原始颜色，值距离0越远，饱和度越高，并改变色相
        },
        0,
        false
      )
    } else {
      modifyMap(
        window.viewer,
        {
          //反色?
          invertColor: true, //反色
          // filterRGB: [10, 49, 85], //过滤器rgb
          filterRGB: [0, 52, 68], //过滤器rgb
          brightness: 0.55, //亮度，值0=1，小于1会减少亮度，大于1会增加亮度
          contrast: 2.58, //对比度，值0=1，小于1会减少对比度、亮度，大于1会增加对比度、亮度
          gamma: 0.1, //值0=1，小于1会增加对比度，大于1会减少对比度
          hue: 0, //颜色，值能为0，可以为正负数，接近0为原始颜色，改变饱和度，轻微改变色相
          saturation: 0.1, //饱和度+色相，值不能为0，可以为正负数，接近0为原始颜色，值距离0越远，饱和度越高，并改变色相
        },
        0,
        true
      )
    }
  }

  /**
   * @切换瓦片地图
   */
  const changBaseMap = (layer) => {
    // 定义本地瓦片底图的URL
    // var localTilesetUrl = `/${layer}/Mapnik/{z}/{x}/{y}.png`
    var localTilesetUrl = `/mapApi/${layer}/Mapnik/{z}/{x}/{y}.png`
    // 创建ImageryProvider
    var localTileProvider = new Cesium.UrlTemplateImageryProvider({
      url: localTilesetUrl,
    })

    // 创建ImageryLayer并添加到Viewer中
    viewer.imageryLayers.addImageryProvider(localTileProvider)
  }

  /**
   * @添加白模
   */
  let titlesObj = null
  const add3DTiles = async () => {
    /* 加载建筑模型 */
    try {
      let url = '/3DTiles/architecture/cs/tileset.json'
      const tileset = await Cesium.Cesium3DTileset.fromUrl(url, {
        skipLevelOfDetail: true,
        baseScreenSpaceError: 1024,
        maximumScreenSpaceError: 256, // 数值加大，能让最终成像变模糊
        skipScreenSpaceErrorFactor: 16,
        skipLevels: 1,
        immediatelyLoadDesiredLevelOfDetail: false,
        loadSiblings: true, // 如果为true则不会在已加载完概况房屋后，自动从中心开始超清化房屋
        cullWithChildrenBounds: true,
        cullRequestsWhileMoving: true,
        cullRequestsWhileMovingMultiplier: 10, // 值越小能够更快的剔除
        preloadWhenHidden: true,
        preferLeaves: true,
        maximumMemoryUsage: 128, // 内存分配变小有利于倾斜摄影数据回收，提升性能体验
        progressiveResolutionHeightFraction: 0.5, // 数值偏于0能够让初始加载变得模糊
        dynamicScreenSpaceErrorDensity: 0.5, // 数值加大，能让周边加载变快
        dynamicScreenSpaceErrorFactor: 1, // 不知道起了什么作用没，反正放着吧先
        dynamicScreenSpaceError: true, // 根据测试，有了这个后，会在真正的全屏加载完之后才清晰化房屋
        zIndex: 100,
      })
      tileset.maximumScreenSpaceError = 60
      var tilesetData = viewer.scene.primitives.add(tileset)
      tileset.show = true

      // /* 设置颜色 */
      tileset.style = new Cesium.Cesium3DTileStyle({
        color: {
          conditions: [['true', "color('rgb(0, 120, 152)',1)"]],
        },
      })
      let customShader = new Cesium.CustomShader({
        lightingModel: Cesium.LightingModel.UNLIT,
        fragmentShaderText: `
                                       void fragmentMain(FragmentInput fsInput, inout czm_modelMaterial material) {
                                           float _baseHeight = 0.0; // 物体的基础高度，需要修改成一个合适的建筑基础高度
                                          float _heightRange = 60.0; // 高亮的范围(_baseHeight ~ _baseHeight + _      heightRange) 默认是 0-60米
                                          float _glowRange = 300.0; // 光环的移动范围(高度)
                                           float vtxf_height = fsInput.attributes.positionMC.z-_baseHeight;
                                           float vtxf_a11 = fract(czm_frameNumber / 120.0) * 3.14159265 * 2.0;
                                           float vtxf_a12 = vtxf_height / _heightRange + sin(vtxf_a11) * 0.1;
                                           material.diffuse*= vec3(vtxf_a12, vtxf_a12, vtxf_a12);
                                           float vtxf_a13 = fract(czm_frameNumber / 360.0);
                                           float vtxf_h = clamp(vtxf_height / _glowRange, 0.0, 1.0);
                                           vtxf_a13 = abs(vtxf_a13 - 0.5) * 2.0;
                                           float vtxf_diff = step(0.005, abs(vtxf_h - vtxf_a13));
                                           material.diffuse += material.diffuse * (1.0 - vtxf_diff);
                                       }
                                       `,
      })
      tileset.customShader = customShader
      titlesObj = tileset
      // 调整模型位置
      tileSet(tilesetData, 112.9895, 28.2266, 0)
    } catch (error) {
      console.error(`Error creating tileset: ${error}`)
    }
  }
  /* 利用translation对模型的经度、纬度、高度进行修改 */
  const tileSet = (tileset, longitude, latitude, height) => {
    //3dtile模型的边界球体
    var boundingSphere = tileset.boundingSphere
    //迪卡尔空间直角坐标=>地理坐标（弧度制）
    var cartographic_original = Cesium.Cartographic.fromCartesian(boundingSphere.center)
    //设置新的经度、纬度、高度
    var cartographic_offset = Cesium.Cartographic.fromDegrees(longitude, latitude, height)
    //地理坐标（弧度制）=>迪卡尔空间直角坐标
    var Cartesian3_original = Cesium.Cartesian3.fromRadians(
      cartographic_original.longitude,
      cartographic_original.latitude,
      cartographic_original.height
    )
    var Cartesian3_offset = Cesium.Cartesian3.fromRadians(
      cartographic_offset.longitude,
      cartographic_offset.latitude,
      cartographic_offset.height
    )
    //获得地面和offset的转换
    var translation = Cesium.Cartesian3.subtract(
      Cartesian3_offset,
      Cartesian3_original,
      new Cesium.Cartesian3()
    )
    //修改模型矩阵
    tileset.modelMatrix = Cesium.Matrix4.fromTranslation(translation)
  }

  /**
   * @cesium:绘制多边形
   */
  let companyLayers = [] // 存放 三级防御圈数据
  let companyColorMap = new Map()
  companyColorMap.set(1, '#ff0000') //红色
  companyColorMap.set(5, '#ffaa00') //黄色
  companyColorMap.set(10, '#4d90fe') //蓝色
  companyColorMap.set(0, '#6b798e')
  companyColorMap.set(-1, '#663d74')
  companyColorMap.set(-2, '#94784f')
  const drawPolygon = (data, ex, zIndex = 1, fillOpacity = 0.4) => {
    let positionArr = []
    if (data[ex]) {
      data[ex].forEach((i) => {
        positionArr.push(Number(i.longitude))
        positionArr.push(Number(i.latitude))
      })
    }
    let positions = Cesium.Cartesian3.fromDegreesArray(positionArr)
    let color = companyColorMap.get(Number(data.limitFlyType))
    let polygon = new Cesium.Entity({
      polygon: {
        // 获取指定属性（positions）
        hierarchy: new Cesium.PolygonHierarchy(positions),
        // 填充的颜色，withAlpha透明度
        material: Cesium.Color.fromCssColorString(color).withAlpha(fillOpacity),
        // 是否被提供的材质填充
        fill: true,
        // 是否显示
        show: true,
        // 顺序,仅当`clampToGround`为true并且支持地形上的折线时才有效。
        zIndex: 20 - data.limitFlyType,
      },
      cursorHand: true,
    })
    companyLayers.push(polygon)
    viewer.entities.add(polygon)
  }

  /**
   * @cesium:绘制圆形
   */
  const drawCircle = (data, zIndex = 1, fillOpacity = 0.4) => {
    let position = [Number(data.longitude), Number(data.latitude)]
    let color = companyColorMap.get(Number(data.limitFlyType))
    let circle = new Cesium.Entity({
      position: Cesium.Cartesian3.fromDegrees(...position),
      ellipse: {
        semiMinorAxis: data.radius,
        semiMajorAxis: data.radius,
        outline: false,
        zIndex: 20 - data.limitFlyType,
        material: Cesium.Color.fromCssColorString(color).withAlpha(fillOpacity),
      },
      cursorHand: true,
    })
    companyLayers.push(circle)
    viewer.entities.add(circle)
  }

  /**
   * @防御圈水波纹
   */
  let waveCircleList = []
  const waveCircle = (item, radius = 3000) => {
    // 水波纹扩散
    if (waveCircleList.length > 0) {
      removeView(waveCircleList)
      waveCircleList = []
    }
    let longitude = Number(item[0])
    let latitude = Number(item[1])
    const waveCircles = new Cesium.Entity({
      position: Cesium.Cartesian3.fromDegrees(longitude, latitude),
      name: '波纹圆',
      ellipse: {
        semiMinorAxis: radius,
        semiMajorAxis: radius,
        material: new CircleRippleMaterialProperty({
          color: new Cesium.Color.fromCssColorString('#4d90fe'),
          speed: 5.0,
          count: 1,
          gradient: 0.2,
        }),
        zIndex: 2,
      },
    })
    viewer.entities.add(waveCircles)
    waveCircleList.push(waveCircles)
  }

  /**
   * @description: 经纬度转换 高德转threejs
   * @param {*} lnglat 高德经纬度
   * @return {*} threejs 经纬度
   */
  const setPosition = (lnglat) => {
    var position = aMap.customCoords.lngLatsToCoords([lnglat])[0]
    return position
  }

  /* 尺寸自适应 */
  let scene = null // threejs 场景
  const onWindowResize = () => {
    if (scene) {
      camera.aspect = window.innerWidth / window.innerHeight
      camera.updateProjectionMatrix()
      renderer.setSize(window.innerWidth, window.innerHeight)
    }
  }

  /**
   * @description: 默认视角
   */
  const defaultAngle = () => {
    if (mapCenterData.value.length > 0) {
      viewer.camera.setView({
        destination: Cesium.Cartesian3.fromDegrees(
          mapCenterData.value[0],
          mapCenterData.value[1],
          25000
        ), // 定位点
        orientation: {
          heading: Cesium.Math.toRadians(0.0), // 方向（从正北开始）
          pitch: Cesium.Math.toRadians(-90.0), // 倾斜度（向下）
          roll: 0.0, // 滚动度
        },
      })
    } else {
      /* 设置相机位置-海宁 */
      viewer.camera.setView({
        // 设置相机位置
        destination: {
          x: -2816848.42615148,
          y: 4743740.974434502,
          z: 3230577.710770937,
        },
        orientation: {
          // 初始视角
          heading: 6.28119452736122,
          pitch: -1.5707956694526715,
          roll: 0,
        },
      })
    }
  }

  /**
   * @description: 右下角导航按钮
   */
  const changeNav = (val) => {
    closealldialog()
    selectNav.value = val
    if (val == 'historical') {
      historyShow.value = !historyShow.value
      if (!historyShow.value) {
        selectNav.value = ''
      } else {
        showwhitelistdialog.value = false
        defenseShow.value = false
      }
    } else if (val == 'white-list') {
      showwhitelistdialog.value = !showwhitelistdialog.value
      if (!showwhitelistdialog.value) {
        selectNav.value = ''
      } else {
        historyShow.value = false
        defenseShow.value = false
      }
    } else if (val == 'defense') {
      defenseShow.value = !defenseShow.value
      if (!defenseShow.value) {
        selectNav.value = ''
      } else {
        showwhitelistdialog.value = false
        historyShow.value = false
      }
    }
    if (selectNav.value == 'historical' && historyShow.value) {
      enableTool(false)
    } else {
      enableTool(true)
    }
  }
  /**
   * @description: 是否禁用地图鼠标的缩放平移功能
   */
  const enableTool = (val) => {
    // 禁止缩放功能
    viewer.scene.screenSpaceCameraController.enableZoom = val

    // 禁止旋转功能
    viewer.scene.screenSpaceCameraController.enableRotate = val

    // 禁止平移功能
    viewer.scene.screenSpaceCameraController.enableTranslate = val
  }

  /**
   * @description: 点击布防管理按钮
   */
  const selectDefense = (index) => {
    closealldialog()
    defenseIndex.value = index
    if (index == 1) {
      showdevicedialog.value = true
      coverageShow.value = false
    } else {
      showdevicedialog.value = false
      coverageShow.value = true
    }
  }
  /**
   * @description: 关闭历史弹窗
   */
  const closeNav = (val) => {
    if (val == 'historical') {
      historyShow.value = false
    } else if (val == 'white-list') {
      showwhitelistdialog.value = false
    } else if (val == 'defense') {
      showdevicedialog.value = false
      defenseIndex.value = 0
      defenseShow.value = false
      coverageShow.value = false
    }
    selectNav.value = ''
    enableTool(true)
  }

  /**
   * @description: 获取在飞列表数据
   */
  const getRealTimeList = async (type) => {
    let res = await hisDroneDirect()
    console.log('res', res)
    if (res.code == 200) {
      // 筛选数据
      if (type == 'all') {
      } else if (type == 'direction') {
        res.data = res.data.filter((jtem) => {
          return jtem.type == 1
        })
      } else if (type == 'positioning') {
        res.data = res.data.filter((jtem) => {
          return jtem.type == 2
        })
      } else if (type == 'decoding') {
        res.data = res.data.filter((jtem) => {
          return jtem.type == 5
        })
      } else if (type == 'minghang') {
        res.data = res.data.filter((jtem) => {
          return jtem.type == 7
        })
      }
      let arr = []
      res.data.map((item) => {
        //转换坐标系
        let curarr = gcj02towgs84(item.curLongitude, item.curLatitude)
        let driverarr = gcj02towgs84(item.driverLongitude, item.driverLatitude)
        item.realModel = item.model
        item.curLongitude = curarr[0]
        item.curLatitude = curarr[1]
        item.driverLongitude = driverarr[0]
        item.driverLatitude = driverarr[1]
        //初始化页面就有在哪个防御圈
        let arr = []
        if (item.companys && item.companys.length > 0) {
          arr = item.companys.filter((jtem) => {
            return jtem.companyId == companyInfoStore.state.companyInfo.companyId
          })
        }

        if (arr.length > 0) {
          item.defenseType = arr[arr.length - 1].defenseType
        }
        // item.defenseType = 3
        console.log('')
        item.code = item.intrusionStartTime
        item.batchNo = item.batchNum
        item.lastTime = +new Date()
        arr.push(item.droneCode)
      })
      realtimeList.value = res.data
      droneStore.setUavflynowdata(arr)
      drawRealTime(res.data)
    }
  }
  /**
   * @description: 获取侦测列表历史数据
   */
  const hist_comdetect = async (type) => {
    let res = await comdetect({
      pageNum: 1,
      pageSize: 50,
    })
    if (type == 'all') {
    } else if (type == 'direction') {
      res.records = res.records.filter((jtem) => {
        return jtem.type == 1
      })
    } else if (type == 'positioning') {
      res.records = res.records.filter((jtem) => {
        return jtem.type == 2
      })
    } else if (type == 'decoding') {
      res.records = res.records.filter((jtem) => {
        return jtem.type == 5
      })
    } else if (type == 'minghang') {
      res.records = res.records.filter((jtem) => {
        return jtem.type == 7
      })
    }
    hisroryList.value = res.records.slice(0, 10) //约定只需取10条
  }

  /**
   * @description: 接受推送数据 生产 在飞无人机列表
   * @param {*} info mqtt 推送的数据 type == 1
   */
  let whetherTimeSorted = false
  watch(droneStore.newflystate, (newValue) => {
    whetherTimeSorted = true
    console.log('whetherTimeSorted变成了true')
  })
  const nowflyData = (info) => {
    if (!!info) {
      let newTime = +new Date()
      let flydata = JSON.parse(info)
      flydata.lastTime = +new Date()
      let oldList = realtimeList.value
      let list = []
      let newArr = []
      //判断droneCode是否在之前的数组中找出下标
      const exists = oldList.findIndex((item) => item.droneCode === flydata.droneCode)
      if (exists != -1) {
        // 根据下标 更新数据
        oldList[exists] = { ...flydata } // 使用对象的扩展运算符复制flydata的属性到oldList[i]
      } else {
        let data
        if (flydata.data) {
          data = {
            ...flydata,
            ...JSON.parse(flydata.data),
          }
        } else {
          data = flydata
        }

        list.unshift(data)
      }

      function unique(arr1, uniId) {
        const res = new Map()
        return arr1.filter((item) => !res.has(item[uniId]) && res.set(item[uniId], 1))
      }

      // 根据防御圈 排序
      if (list.length > 0) {
        let list1 = [...list, ...oldList]
        // 根据 无人机 dronCode 去重defenseType
        newArr = unique(list1, 'droneCode')
      } else {
        newArr = JSON.parse(JSON.stringify(unique(oldList, 'droneCode'))).reverse()
        // newArr = JSON.parse(JSON.stringify(unique(oldList, 'droneCode')))
      }

      realtimeList.value = []
      newArr.forEach((item) => {
        item.code = item.intrusionStartTime
        item.batchNo = item.batchNum
        item.takeoffTime = dayjs(item.takeoffTime).format('YYYY-MM-DD HH:mm:ss')
        try {
          //无人机在什么防御圈
          let list = []
          let companys = item.companys
          // item.defenseType = 3
          item.defenseType = null
          companys.map((i) => {
            if (i.companyId == companyInfoStore.state.companyInfo.companyId) {
              item.defenseType = i.defenseType
            }
          })
          item.realModel = item.model
          list.push(item)
        } catch (error) {}
        if (item.data) {
          let data = JSON.parse(item.data)
          let info = {
            ...item,
            ...data,
            takeoffTime: dayjs(data.takeoffTime).format('YYYY-MM-DD HH:mm:ss'),
            realModel: data.model,
          }

          realtimeList.value.unshift(info)
        } else {
          realtimeList.value.unshift(item)
        }
      })
      // exists != -1
      // whetherTimeSorted
      if (exists == -1) {
        console.log('执行了排序')
        console.log('realtimeList', realtimeList.value)
        let droneList = realtimeList.value.sort(function (item1, item2) {
          let takeTime1 = Date.parse(item1.takeoffTime)
          let takeTime2 = Date.parse(item2.takeoffTime)
          if (takeTime1 === takeTime2) {
            let lastTime1 = Date.parse(item1.lastTime)
            let lastTime2 = Date.parse(item2.lastTime)
            if (lastTime1 === lastTime2) {
              return Math.round(Math.random()) - 0.5
            }
            return Math.sign(lastTime1 - lastTime1) // 修改这里，改为降序排序
          }
          return Math.sign(takeTime2 - takeTime1) // 修改这里，改为降序排序
        })
        realtimeList.value = droneList
        whetherTimeSorted = false
      }
      // 筛选数据
      if (realtime.value.dataType == 'all') {
      } else if (realtime.value.dataType == 'direction') {
        realtimeList.value = realtimeList.value.filter((jtem) => {
          return jtem.type == 1
        })
      } else if (realtime.value.dataType == 'positioning') {
        realtimeList.value = realtimeList.value.filter((jtem) => {
          return jtem.type == 2
        })
      } else if (realtime.value.dataType == 'decoding') {
        realtimeList.value = realtimeList.value.filter((jtem) => {
          return jtem.type == 5
        })
      } else if (realtime.value.dataType == 'minghang') {
        realtimeList.value = realtimeList.value.filter((jtem) => {
          return jtem.type == 7
        })
      }
      // realtimeList.value = realtimeList.value.sort((a, b) => b.defenseType - a.defenseType)

      droneStore.setDroneGroup(realtimeList.value)
    }
  }

  //地图》》》》》》》》》》》》》》》》》》》》》》
  /**
   * @description: 绘制车设备位置
   */
  let carPositon = []
  let devicePosition = [
    [0, -80],
    [-31, -68],
    [31, -68],
    [42, -36],
    [-42, -36],
    [-28, -6],
    [28, -6],
  ]
  let cariconArr = [] //车载图标数组
  let omnidirectionalPoint = null //全向反制设备
  let directionalPoint = null //定向反制设备
  let aoaPoint = null //aoa侦测设备
  let radarPoint = null //雷达侦测设备
  let decodingPoint = null //解码侦测设备
  let adsbPoint = null //adsb侦测设备
  let carPoint = null //反制车
  const drawCardevice = () => {
    // if (cariconArr.length > 0) {
    //   cariconArr.forEach((item) => {
    //     viewer.entities.remove(item)
    //   })
    // }
    getDeviceInfo(601).then((res) => {
      if (res.code == 200) {
        // console.log('deviceDetail', counterequipment.value.DeviceList)
        // let convertArr = gcj02towgs84(res.data.longitude, res.data.latitude)
        res.data.longitude = res.data.gpsLongitude
        res.data.latitude = res.data.gpsLatitude
        counterequipment.value?.DeviceList.forEach((item, index) => {
          //初始化反制数组
          if (item.deviceType == 5) {
            deviceCount[item.id] = {}
          } else if (item.deviceType == 4) {
            deviceCount[item.id] = {}
          }

          switch (Number(item.deviceType)) {
            case 4:
              //全向
              //全向反制设备
              if (!omnidirectionalPoint) {
                omnidirectionalPoint = new Cesium.Entity({
                  name: 'omnidirectional',
                  info: item,
                  show: true,
                  position: Cesium.Cartesian3.fromDegrees(
                    Number(res.data.longitude),
                    Number(res.data.latitude),
                    0
                  ),
                  billboard: {
                    //这里需要改成您本地的路径的图片信息。
                    image: '/img/omnidirectional.png',
                    height: 30,
                    width: 30,
                    disableDepthTestDistance: Number.POSITIVE_INFINITY,
                    pixelOffset: new Cesium.Cartesian2(...devicePosition[index]), // 设置偏移量，这里是向上偏移 30 像素
                  },
                })
                viewer.entities.add(omnidirectionalPoint)
                cariconArr.push(omnidirectionalPoint)
              } else {
                omnidirectionalPoint.position = Cesium.Cartesian3.fromDegrees(
                  Number(res.data.longitude),
                  Number(res.data.latitude),
                  0
                )
              }
              break
            case 5:
              //定向
              //定向反制设备
              if (!directionalPoint) {
                directionalPoint = new Cesium.Entity({
                  name: 'directional',
                  info: item,
                  show: true,
                  position: Cesium.Cartesian3.fromDegrees(
                    Number(res.data.longitude),
                    Number(res.data.latitude),
                    0
                  ),
                  billboard: {
                    //这里需要改成您本地的路径的图片信息。
                    image: '/img/directional.png',
                    height: 30,
                    width: 30,
                    disableDepthTestDistance: Number.POSITIVE_INFINITY,
                    pixelOffset: new Cesium.Cartesian2(...devicePosition[index]), // 设置偏移量，这里是向上偏移 30 像素
                  },
                })
                viewer.entities.add(directionalPoint)
                cariconArr.push(directionalPoint)
              } else {
                directionalPoint.position = Cesium.Cartesian3.fromDegrees(
                  Number(res.data.longitude),
                  Number(res.data.latitude),
                  0
                )
              }

              break
            case 7:
              //aoa
              //aoa侦测设备
              if (!aoaPoint) {
                aoaPoint = new Cesium.Entity({
                  name: 'aoa',
                  info: item,
                  show: true,
                  position: Cesium.Cartesian3.fromDegrees(
                    Number(res.data.longitude),
                    Number(res.data.latitude),
                    0
                  ),
                  billboard: {
                    //这里需要改成您本地的路径的图片信息。
                    image: '/img/aoa.png',
                    height: 30,
                    width: 30,
                    disableDepthTestDistance: Number.POSITIVE_INFINITY,
                    pixelOffset: new Cesium.Cartesian2(...devicePosition[index]), // 设置偏移量，这里是向上偏移 30 像素
                  },
                })
                viewer.entities.add(aoaPoint)
                cariconArr.push(aoaPoint)
              } else {
                aoaPoint.position = Cesium.Cartesian3.fromDegrees(
                  Number(res.data.longitude),
                  Number(res.data.latitude),
                  0
                )
              }
              break
            case 8:
              //雷达
              //雷达侦测设备
              if (!radarPoint) {
                radarPoint = new Cesium.Entity({
                  name: 'radar',
                  info: item,
                  show: true,
                  position: Cesium.Cartesian3.fromDegrees(
                    Number(res.data.longitude),
                    Number(res.data.latitude),
                    0
                  ),
                  billboard: {
                    //这里需要改成您本地的路径的图片信息。
                    image: '/img/radar.png',
                    height: 30,
                    width: 30,
                    disableDepthTestDistance: Number.POSITIVE_INFINITY,
                    pixelOffset: new Cesium.Cartesian2(...devicePosition[index]), // 设置偏移量，这里是向上偏移 30 像素
                  },
                })
                viewer.entities.add(radarPoint)
                cariconArr.push(radarPoint)
              } else {
                radarPoint.position = Cesium.Cartesian3.fromDegrees(
                  Number(res.data.longitude),
                  Number(res.data.latitude),
                  0
                )
              }
              break
            case 9:
              //小云哨
              //解码侦测设备
              if (!decodingPoint) {
                decodingPoint = new Cesium.Entity({
                  name: 'decoding',
                  show: true,
                  info: item,
                  position: Cesium.Cartesian3.fromDegrees(
                    Number(res.data.longitude),
                    Number(res.data.latitude),
                    0
                  ),
                  billboard: {
                    //这里需要改成您本地的路径的图片信息。
                    image: '/img/decoding.png',
                    height: 30,
                    width: 30,
                    disableDepthTestDistance: Number.POSITIVE_INFINITY,
                    pixelOffset: new Cesium.Cartesian2(...devicePosition[index]), // 设置偏移量，这里是向上偏移 30 像素
                  },
                })
                viewer.entities.add(decodingPoint)
                cariconArr.push(decodingPoint)
              } else {
                decodingPoint.position = Cesium.Cartesian3.fromDegrees(
                  Number(res.data.longitude),
                  Number(res.data.latitude),
                  0
                )
              }

              break
            case 10:
              //ads-b
              //adsb侦测设备
              if (!adsbPoint) {
                adsbPoint = new Cesium.Entity({
                  name: 'adsb',
                  show: true,
                  info: item,
                  position: Cesium.Cartesian3.fromDegrees(
                    Number(res.data.longitude),
                    Number(res.data.latitude),
                    0
                  ),
                  billboard: {
                    //这里需要改成您本地的路径的图片信息。
                    image: '/img/adsb.png',
                    height: 30,
                    width: 30,
                    disableDepthTestDistance: Number.POSITIVE_INFINITY,
                    pixelOffset: new Cesium.Cartesian2(...devicePosition[index]), // 设置偏移量，这里是向上偏移 30 像素
                  },
                })
                viewer.entities.add(adsbPoint)
                cariconArr.push(adsbPoint)
              } else {
                adsbPoint.position = Cesium.Cartesian3.fromDegrees(
                  Number(res.data.longitude),
                  Number(res.data.latitude),
                  0
                )
              }
              break
            default:
              break
          }
        })
        carPositon = [Number(res.data.longitude), Number(res.data.latitude)]
        //地图中心点
        mapCenterData.value = carPositon
        //围绕车的三级防御圈
        drawDenfens(carPositon)
        //车
        if (!carPoint) {
          carPoint = new Cesium.Entity({
            name: 'car',
            show: true,
            position: Cesium.Cartesian3.fromDegrees(
              Number(res.data.longitude),
              Number(res.data.latitude),
              0
            ),
            billboard: {
              //这里需要改成您本地的路径的图片信息。
              image: '/img/car.png',
              height: 64,
              width: 50,
              disableDepthTestDistance: Number.POSITIVE_INFINITY,
              pixelOffset: new Cesium.Cartesian2(0, -32), // 设置偏移量，这里是向上偏移 30 像素
            },
          })
          viewer.entities.add(carPoint)
          cariconArr.push(carPoint)
        } else {
          carPoint.position = Cesium.Cartesian3.fromDegrees(
            Number(res.data.longitude),
            Number(res.data.latitude),
            0
          )
        }

        //光电反制设备
        let photoelectricityPoint = new Cesium.Entity({
          name: 'photoelectricity ',
          show: true,
          position: Cesium.Cartesian3.fromDegrees(
            Number(res.data.longitude),
            Number(res.data.latitude),
            0
          ),
          billboard: {
            //这里需要改成您本地的路径的图片信息。
            image: '/img/photoelectricity.png',
            height: 30,
            width: 30,
            disableDepthTestDistance: Number.POSITIVE_INFINITY,
            pixelOffset: new Cesium.Cartesian2(31, -68), // 设置偏移量，这里是向上偏移 30 像素
          },
        })

        // viewer.entities.add(photoelectricityPoint)
      }
    })
  }
  /**
   * @description: 绘制定向设备扇形
   */
  let orientationSector = [] //定向反制的数组
  const Draworientation = () => {
    getdeviceAngle({
      deviceIds: [
        {
          deviceId: 586,
        },
      ],
    }).then(({ data }) => {
      //扇形夹角
      let sectorAngle = data[0].includedAngle ? data[0].includedAngle : 120
      let angle = Number(data[0].horizontal_angle) + Number(data[0].northbound_angle)
      if (orientationSector.length > 0) {
        orientationSector.map((item) => {
          viewer.entities.remove(item)
        })
        orientationSector = []
      }
      drawFanBorder(
        ...carPositon,
        angle,
        sectorAngle,
        3000,
        orientationSector,
        '#c1bd68',
        0.5,
        1,
        0.5
      )
    })
  }

  /**
   * @description: 开启/关闭 设备信息
   * @param {*} type 类型 1 开启 2 关闭
   * @param {*} item 设备信息
   */
  const showDronePopup = ref('') // 驾驶舱弹窗
  const deviceInfo = ref({}) // 设备信息
  const hidepopver = ref(false) // 图层控制的显示/隐藏
  const showDeviceInfo = (type, item) => {
    clearHistorInfo()
    clearRealTimeInfo()
    clearaoaPoint()
    drawState = null
    droneKey = null
    beforeDroneList = []
    showTrajectory = 0
    if (showDronePopup.value == 'droneDetail') {
      offDroneDetail()
    }
    if (type === 2) {
      showDronePopup.value = ''
      showdeviceDetail.value = false
      defaultAngle()
    } else if (type === 1) {
      hidepopver.value = false
      showDronePopup.value = 'equipmentDetail'
    }
  }
  /**
   * @description: 设备列表跳转
   */
  const Jumpdevicedialog = (info) => {
    if (showTrajectory == 1) {
      offDroneDetail()
    }
    showdeviceDetail.value = true
    deviceInfo.value = info
    // 调整轨迹展示的视角
    let centeropt = {}
    viewer.camera.flyTo({
      destination: Cesium.Cartesian3.fromDegrees(...carPositon, centeropt.z || 7000), //经度、纬度、高度
      orientation: {
        heading: Cesium.Math.toRadians(centeropt.heading || 0), //绕垂直于地心的轴旋转
        pitch: Cesium.Math.toRadians(-90), //绕纬度线旋转
        roll: Cesium.Math.toRadians(centeropt.roll || 0), //绕经度线旋转
      },
      duration: 3,
    })
  }

  /**
   * @description: 设备开启
   * @param {*} item 当前设备数据
   * @param {*} type 操作类型
   * @param {*} equipmentType 1 设备弹窗端 开启
   */
  let unmanned = ref({}) //存储无人值守开启的
  const changeDisposal = async (item, type, equipmentType) => {
    // 反制类型：0-迫降 1-驱离 3-无人值守
    item.counterType = type
    let res = await getcallDevice({
      deviceId: item.id,
      strikeSeconds: 60,
      cityId: 28670,
      strikeType: type,
      strikeCircuit: 1,
    })
    if (res.code == 200 || res.code == 201) {
      ElMessage.success('指令下发成功')
      drawDeviceAnimation(item)
    }
  }
  /**
   * @description: 绘制实时无人机位置
   * @param {*} data 分组后的在飞无人机数据
   */
  const drawRealTime = (data) => {
    // console.log('data', data)
    //清除无人机图标
    if (realtimeList_drone.length > 0) {
      removeView(realtimeList_drone)
      realtimeList_drone = []
    }
    if (data.length > 0 && showTrajectory == 0) {
      data.map((i) => {
        let item = i

        if (!isNaN(i.curLongitude)) {
          let titleName = ''
          let iconName = ''

          if (i.type == 1 || i.type == 2 || i.type == 5) {
            //黑飞无人机
            titleName = '黑飞无人机'
            iconName = 'heifei'
          } else if (i.type == 3) {
            if (i.policeDrone !== 1) {
              // 白名单无人机
              titleName = '白名单无人机'
              iconName = 'baiminwu'
            } else {
              //警用无人机
              titleName = '警用无人机'
              iconName = 'police'
            }
          } else if (i.type == 4) {
            //行业无人机
            titleName = '行业无人机'
            iconName = 'trade'
          } else if (i.type == 7) {
            //民航
            titleName = '民航'
            iconName = 'minghang'
          }
          i.name = titleName
          i.icon = `/img/${iconName}.png`
          let markerList = drawMarker([i])
          realtimeList_drone.push(...markerList)
        }
      })
    }
  }

  /**
   * @cesium添加图标
   * @pointArr 添加点位的数组
   * @flag 是否是设备
   */
  const drawMarker = (pointArr, flag = false) => {
    // //清空设备图标
    // removeView(equipmentArr)
    // equipmentArr = []
    // if(uavArr.length>0){
    //   removeView(uavArr)
    //   uavArr=[]
    // }
    let arr = []
    if (pointArr.length < 1) return

    pointArr.forEach((item) => {
      if (flag && item.type == 2) {
        let obj = {
          timer: null,
          count: 60,
          countdown: true,
        }
        deviceCountBtn.value[item.deviceId] = true
        deviceCount[item.deviceId] = obj
        deviceCount[item.deviceId].counterType = ''
      }
      // console.log('item', item)
      // console.log('img', item.icon)
      let point = new Cesium.Entity({
        // id: item.id,
        name: item.name,
        position: Cesium.Cartesian3.fromDegrees(
          Number(item.longitude || item.curLongitude),
          Number(item.latitude || item.curLatitude),
          item.height || 0
        ),
        billboard: {
          //这里需要改成您本地的路径的图片信息。
          image: item.icon ? item.icon : item.icon,
          height: 40,
          width: 40,
          disableDepthTestDistance: Number.POSITIVE_INFINITY,
        },
        typeId: item.typeId,
        batchNo: item.batchNo,
        data: item,
        cursorHand: true,
        pointPosition: [
          Number(item.longitude || item.curLongitude),
          Number(item.latitude || item.curLatitude),
        ],
      })
      viewer.entities.add(point)
      // uavArr.push(point)
      arr.push(point)
    })
    return arr
  }

  /**
   * @cesium移除地图标记
   */
  const removeView = (list) => {
    if (list.length < 1) return
    list.forEach((item) => {
      viewer.entities.remove(item)
    })
  }

  /**
   * @description: 绘制实时轨迹 - 结合实时
   * @param {*} code 当前无人机code
   * @param {*} key 当前无人机id 调取之前的轨迹
   * @param {*} Info 当前无人机信息
   * @param {*} type 是否移动层级
   */
  let moveZoom = 1 // 是否移动
  let realtimeList_drone = [] // 实时无人机点
  let addPolycodeline = [] //实时无人机轨迹
  const droneInfo = ref({}) //无人机轨迹信息
  let aoaSectorArr = [] //
  const drawRealTimeRajectory = async (code, key = null, Info = null, type = 2) => {
    // offDroneDetail()
    moveZoom = type
    //当前无人机轨迹制空重新画
    if (code) {
      showTrajectory = 1
      if (realtimeList_drone.length != 0) {
        removeView(realtimeList_drone)
        realtimeList_drone = []
      }
      let list = [] // 无人机轨迹信息
      drawState = code // 绘制无人机轨迹的无人机id
      let droneType = 1 // 无人机轨迹类型 1 正常轨迹 2 AOA 设备位置
      // 接口数据
      if (key != null) {
        try {
          const res = await hisDroneCoors({ droneKey: key })
          if (res.code == 200) {
            droneType = res.data.type
            //置空疑似飞手
            suspectedInfo.value = {}
            res.data.coors.map((item) => {
              if (Info != null) {
                item.model = Info.model
                item.batchNum = Info.batchNum
                item.takeoffTime = Info.takeoffTime
                item.droneCode = Info.droneCode
              }
              if (Info.aoaDevId) {
                item.aoaDevId = Info.aoaDevId
              }
              item.curLongitude = Number(item.longitude)
              item.curLatitude = Number(item.latitude)
              item.driverLongitude = res.data.driverLongitude
              item.driverLatitude = res.data.driverLatitude
              item.curSpeed = Number(item.speed)
              item.curFrequency = item.frequency
              item.power = null
              item.curHeight = Number(item.height)
              item.lastTime = +new Date(item.lastCoorDate)
              beforeDroneList.push(item)
              if (!!Info.direction == false) {
                Info.direction = item.direction
              }
              if (!!Info.distance == false) {
                Info.distance = item.distance
              }
              if (!!Info.curFrequency == false) {
                Info.curFrequency = item.curFrequency
              }
              if (!!Info.curHeight == false) {
                Info.curHeight = item.curHeight
              }
              if (!!Info.curSpeed == false) {
                Info.curSpeed = item.curSpeed
              }
              if (!!Info.driverLongitude == false) {
                Info.driverLongitude = res.data.driverLongitude
                Info.driverLatitude = res.data.driverLatitude
              }
              list = [...beforeDroneList]
            })
            // if (Info.droneSeriaID != null) {
            //   getDriverInfoBySerialCode(Info.droneSeriaID)
            // }
          }
        } catch (error) {
          if (error.response.data.code == 405) {
            getRealTimeList() //获取在飞列表
            offDroneDetail()
          }
        }
      } else {
        list = beforeDroneList
      }
      // if (!!Info.curLatitude) {
      //   droneType = Info.type
      //   list.push(Info)
      // }
      /* 处理无人机信息 */
      if (!!Info) {
        Info.takeoffTime = dayjs(Info.takeoffTime).format('YYYY-MM-DD HH:mm:ss')
        if (Info.curLatitude && Info.curLongitude) {
          // _this.historicalTrack = [];
          list.push(Info)
          beforeDroneList = list
        }
        droneType = Info.type
        if (!!Info.direction == false) {
          Info.direction = Info.curDirection
        }
        if (!!Info.distance == false) {
          Info.distance = Info.curDistance
        }
      }

      // 数组排序
      function compare(property) {
        return function (a, b) {
          var value1 = +new Date(a[property])
          var value2 = +new Date(b[property])
          return value1 - value2
        }
      }

      list.sort(compare('lastTime'))

      if (list.length == 0) {
        offDroneDetail()
        return
      }
      let lastData = list[list.length - 1]
      // // 轨迹播放时视角定位
      // if (type == 1) {
      //   if (Info.curLatitude && Info.curLongitude) {
      //     aMap.setZoomAndCenter(18, [Number(Info.curLongitude), Number(Info.curLatitude)])
      //   } else {
      //     aMap.setZoomAndCenter(18, [Number(lastData.curLongitude), Number(lastData.curLatitude)])
      //   }
      // }
      // 更新数据
      /* 清空 无人机信息弹窗 详情 */
      droneInfo.value = {}
      if (!lastData.direction) {
        lastData.direction = 0
      }
      if (!lastData.distance) {
        lastData.distance = 0
      }
      droneInfo.value = {
        showType: 1,
        droneID: lastData.batchNum,
        droneModel: lastData.model,
        departureTime: dayjs(lastData.takeoffTime).format('YYYY-MM-DD HH:mm:ss'),
        flyingLon: lastData.driverLongitude,
        flyingLat: lastData.driverLatitude,
        spectrum: lastData.curFrequency,
        curLon: lastData.curLongitude,
        curLat: lastData.curLatitude,
        height: lastData.curHeight,
        speed: lastData.curSpeed,
        info: lastData,
        type: lastData.type,
      }

      let iconUrl = 'heifei'
      if (list[list.length - 1].type == 1 || list[list.length - 1].type == 2) {
        /* 黑飞无人机 */
        iconUrl = 'heifei'
      } else if (list[list.length - 1].type == 3) {
        if (list[list.length - 1].policeDrone !== 1) {
          /* 白名单无人机 */
          iconUrl = 'baiminwu'
        } else {
          /* 警用无人机 */
          iconUrl = 'police'
        }
      } else if (list[list.length - 1].type == 4) {
        /* 行业无人机 */
        iconUrl = 'trade'
      } else if (list[list.length - 1].type == 7) {
        /* 行业无人机 */
        iconUrl = 'minghang'
      }
      // droneType == 2 AOA 设备推送数据
      clearRealTimeInfo()
      showTrajectory = 1
      if (droneType != 2) {
        // if (moveZoom == 1) {
        //   aMap.setZoomAndCenter(
        //     18,
        //     [Number(lastData.curLongitude), Number(lastData.curLatitude)],
        //     false,
        //     1000
        //   )
        //   moveZoom = 2
        // }

        let arr = []
        list.map((q) => {
          arr.push([q.curLongitude, q.curLatitude, 0])
        })
        let trackData = {
          isTrack: true,
          list: arr,
          speed: 1000,
          droneIcon: `/img/${iconUrl}.png`,
          driverIcon: '/img/icon-drone-start.png',
          color: '#f00',
          type: Info.type,
        }
        if (key != null) {
          // 调整轨迹展示的视角
          let centeropt = {}
          viewer.camera.flyTo({
            destination: Cesium.Cartesian3.fromDegrees(
              trackData.list[0][0],
              trackData.list[0][1],
              7000
            ), //经度、纬度、高度
            orientation: {
              heading: Cesium.Math.toRadians(centeropt.heading || 0), //绕垂直于地心的轴旋转
              pitch: Cesium.Math.toRadians(-90), //绕纬度线旋转
              roll: Cesium.Math.toRadians(centeropt.roll || 0), //绕经度线旋转
            },
            duration: 3,
          })
        }
        const { driverPoint, line, dronePoint } = drawFlyRealTimeTrack(trackData)
        flyTrackData.push(driverPoint, line, dronePoint)
      } else if (droneType == 2) {
        let AOACenter = { lon: '', lat: '' }
        let newDroneInfo = list[list.length - 1]
        getDeviceLoc(newDroneInfo.aoaDevId).then((res) => {
          AOACenter = {
            lon: res.data.gpsLongitude,
            lat: res.data.gpsLatitude,
          }
          if (moveZoom == 1) {
            // 调整轨迹展示的视角
            let centeropt = {}
            if (showTrajectory == 1) {
              viewer.camera.flyTo({
                destination: Cesium.Cartesian3.fromDegrees(
                  Number(res.data.gpsLongitude),
                  Number(res.data.gpsLatitude),
                  7000
                ), //经度、纬度、高度
                orientation: {
                  heading: Cesium.Math.toRadians(centeropt.heading || 0), //绕垂直于地心的轴旋转
                  pitch: Cesium.Math.toRadians(-90), //绕纬度线旋转
                  roll: Cesium.Math.toRadians(centeropt.roll || 0), //绕经度线旋转
                },
                duration: 3,
              })
            }
            moveZoom = 2
          }
          drawRadar({
            lon: Number(AOACenter.lon),
            lat: Number(AOACenter.lat),
          })
          if (aoaSectorArr.length > 0) {
            removeView(aoaSectorArr)
            aoaSectorArr = []
          }
          drawSector(
            res.data.gpsLongitude,
            res.data.gpsLatitude,
            lastData.direction == null ? 90 : lastData.direction,
            7.5,
            3000,
            aoaSectorArr,
            'rgba(221,70,88,0.5)'
          )
          setTimeout(() => {
            console.log('lastData', lastData)
            var companyendMarker = new Cesium.Entity({
              id: newDroneInfo.id,
              name: 'point',
              position: Cesium.Cartesian3.fromDegrees(
                Number(newDroneInfo.curLongitude),
                Number(newDroneInfo.curLatitude),
                newDroneInfo.height || 0
              ),
              label: 'UAV',
              billboard: {
                //这里需要改成您本地的路径的图片信息。
                image: require(`/img/icon-drone-end`),
                height: 42,
                width: 42,
                disableDepthTestDistance: Number.POSITIVE_INFINITY,
              },
              cursorHand: true,
              pointPosition: [Number(lastData.driverLongitude), Number(lastData.driverLatitude)],
            })
            viewer.entities.add(companyendMarker)
            let angle = bearing(
              {
                longitude: Number(AOACenter.lon),
                latitude: Number(AOACenter.lat),
              },
              {
                longitude: Number(newDroneInfo.curLongitude),
                latitude: Number(newDroneInfo.curLatitude),
              }
            )
            // angle = Number(angle) - 10;
            // angle = angle < 0 ? 360 + angle : angle;
            // drawDeviceCircles(
            //   Number(AOACenter.lon),
            //   Number(AOACenter.lat),
            //   angle - 10,
            //   20,
            //   5000,
            //   AOAsector,
            //   'red'
            // )
            flystrdata_markers.push(companyendMarker)
          }, 500)
        })
      }
    }
  }

  /**
   * @description:计算两点对于正北方向的朝向角度 [0,360]
   * @param {*} start 开始点 {latitude: 30, longitude: 120}
   * @param {*} end 结束点  {latitude: 30, longitude: 120}
   * @return {*} 角度
   */
  const bearing = (start, end) => {
    let rad = Math.PI / 180,
      lat1 = start.latitude * rad,
      lat2 = end.latitude * rad,
      lon1 = start.longitude * rad,
      lon2 = end.longitude * rad
    const a = Math.sin(lon2 - lon1) * Math.cos(lat2)
    const b =
      Math.cos(lat1) * Math.sin(lat2) - Math.sin(lat1) * Math.cos(lat2) * Math.cos(lon2 - lon1)

    return radiansToDegrees(Math.atan2(a, b))
  }
  /*
   * 弧度转换为角度
   */
  const radiansToDegrees = (radians) => {
    const degrees = radians % (2 * Math.PI)
    return (degrees * 180) / Math.PI < 0
      ? 360 + (degrees * 180) / Math.PI
      : (degrees * 180) / Math.PI
  }

  /**
   * @description: 绘制AOA 设备雷达效果
   * @param {*} center 设备坐标
   */
  const AOARadar = {} // 计算AOA 设备 雷达效果的具体点
  const drawRadar = (center) => {
    for (let index = 0; index < 5; index++) {
      AOARadar[`East${index + 1}`] = calculatingTargetPoints(
        Number(center.lon),
        Number(center.lat),
        0,
        90 * (Math.PI / 180),
        1000 * (index + 1)
      )
      AOARadar[`South${index + 1}`] = calculatingTargetPoints(
        Number(center.lon),
        Number(center.lat),
        0,
        180 * (Math.PI / 180),
        1000 * (index + 1)
      )

      AOARadar[`West${index + 1}`] = calculatingTargetPoints(
        Number(center.lon),
        Number(center.lat),
        0,
        270 * (Math.PI / 180),
        1000 * (index + 1)
      )

      AOARadar[`North${index + 1}`] = calculatingTargetPoints(
        Number(center.lon),
        Number(center.lat),
        0,
        0 * (Math.PI / 180),
        1000 * (index + 1)
      )
    }
    nextTick(() => {
      for (let index = 0; index < 5; index++) {
        drawRadarCircle(
          [Number(center.lon), Number(center.lat)],
          1000 * (index + 1),
          '#60a0bf',
          AOARadarList,
          'solid'
        )
        drawRadarText(
          `${index + 1}km`,
          [AOARadar[`North${index + 1}`][0], AOARadar[`North${index + 1}`][1]],
          AOARadarList
        )
      }
      /* eslint-disable */
      let z = [
        AOARadar['South5'][0],
        AOARadar['South5'][1],
        0,
        AOARadar['North5'][0],
        AOARadar['North5'][1],
        0,
      ]
      let h = [
        AOARadar['East5'][0],
        AOARadar['East5'][1],
        0,
        AOARadar['West5'][0],
        AOARadar['West5'][1],
        0,
      ]
      // eslint-enable
      // drawRadarPolygon(z, '#60a0bf', AOARadarList)
      // drawRadarPolygon(h, '#60a0bf', AOARadarList)
    })
  }

  /**
   * @description 根据位置，方位，距离求经纬度
   * @param {int} lon 中心点经度
   * @param {*} lat 中心点纬度
   * @param {*} height 中心点高度
   * @param {*} direction 方向
   * @param {*} radius 半径
   */
  const calculatingTargetPoints = (lon, lat, height, direction, radius) => {
    //根据位置，方位，距离求经纬度
    let viewPoint = Cesium.Cartesian3.fromDegrees(lon, lat, height)
    let webMercatorProjection = new Cesium.WebMercatorProjection(viewer.scene.globe.ellipsoid)
    let viewPointWebMercator = webMercatorProjection.project(
      Cesium.Cartographic.fromCartesian(viewPoint)
    )
    // *1.14为了解决计算不准确
    let toPoint = new Cesium.Cartesian3(
      viewPointWebMercator.x + radius * 1.14 * Math.cos(direction),
      viewPointWebMercator.y + radius * 1.14 * Math.sin(direction),
      0
    )
    toPoint = webMercatorProjection.unproject(toPoint)
    toPoint = Cesium.Cartographic.toCartesian(toPoint.clone())
    let cartographic = Cesium.Cartographic.fromCartesian(toPoint)
    let point = [
      Cesium.Math.toDegrees(cartographic.longitude),
      Cesium.Math.toDegrees(cartographic.latitude),
    ]
    return point
  }

  /**
   * @description: 绘制雷达圆
   * @param {*} arr 雷达圆 位置
   * @param {*} radius 半径
   * @param {*} color 颜色
   * @param {*} example 存放数组实例  solid
   */
  const drawRadarCircle = (
    arr,
    radius,
    color,
    example,
    strokeStyle,
    fillOpacity = 0,
    fillColor = 'rgba(0, 0, 0, 0)'
  ) => {
    const tt = viewer.entities.add({
      position: Cesium.Cartesian3.fromDegrees(arr[0], arr[1]),
      name: '雷达扫描',
      ellipse: {
        semiMajorAxis: radius,
        semiMinorAxis: radius,
        material: new Cesium.ColorMaterialProperty(
          Cesium.Color.fromCssColorString(fillColor).withAlpha(fillOpacity)
        ),
        height: 0,
        heightReference: Cesium.HeightReference.RELATIVE_TO_GROUND,
        outline: true,
        outlineColor: Cesium.Color.fromCssColorString(color),
      },
    })
    example.push(tt)
  }

  /**
   * @description: 绘制雷达每一格的提示语句
   * @param {*} name 文字标记内容
   * @param {*} arr 文字标记位置
   */
  const drawRadarText = (name, arr, example) => {
    let position = [Number(arr[0]), Number(arr[1])]
    let text = viewer.entities.add({
      name: 'name',
      position: Cesium.Cartesian3.fromDegrees(...position, 0),
      label: {
        //文字标签
        text: name,
        font: '500 20px Helvetica', // 15pt monospace
        scale: 1,
        style: Cesium.LabelStyle.FILL,
        fillColor: Cesium.Color.WHITE,
        eyeOffset: new Cesium.Cartesian3(0.0, 10.0, -15.0),
        verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
        showBackground: false,
      },
    })
    example.push(text)
  }

  //点击开始预警
  let circleWaveList = []
  const circleWave = (lon, lat, height = 0) => {
    // 91.47563680927358, 29.758544766388706, 4263.7654574949465
    let entity = viewer.entities.add({
      position: Cesium.Cartesian3.fromDegrees(lon, lat, height),
      ellipse: {
        semiMinorAxis: 3000,
        semiMajorAxis: 3000,
        // ! 重点
        material: new CircleRippleMaterialProperty({
          // color: new Cesium.Color(1, 1, 0, 0.8),

          color: Cesium.Color.RED.withAlpha(0.8),
          speed: 5.0,
          count: 1,
          gradient: 0.2,
        }),
        zIndex: 30,
      },
    })
    circleWaveList.push(entity)
  }
  /**
   * @description: 绘制扇形边框
   * @param {*} longitude 扇形原点纬度
   * @param {*} latitude 扇形原点经度
   * @param {*} angle 旋转角度 相对于正北
   * @param {*} sectorAngle 扇形夹角
   * @param {*} radius 扇形边长
   * @param {*} example 绘制图形存放数组
   * @param {*} color 绘制图形的颜色
   * @param {*} fillop 图形的填充颜色
   * @param {*} sw 图形的边框大小
   * @param {*} sop  图形的边框颜色透明度
   */
  let FanBorderList = []
  const drawFanBorder = (
    longitude,
    latitude,
    angle,
    sectorAngle = 120,
    radius = 1495,
    example,
    color = '#c1bd68',
    fillop,
    sw,
    sop
  ) => {
    let d1 = angle - sectorAngle / 2 // 扇形起始边
    let d2 = angle + sectorAngle / 2 // 扇形终止边
    let list = [Number(longitude), Number(latitude)]
    for (let i = d1; i < d2; i += 1) {
      let point = calculatingTargetPoints(
        longitude,
        latitude,
        0,
        (90 - i) * (Math.PI / 180),
        radius
      )
      list.push(point[0])
      list.push(point[1])
    }
    list.push(Number(longitude))
    list.push(Number(latitude))

    let tt = viewer.entities.add({
      polygon: {
        hierarchy: Cesium.Cartesian3.fromDegreesArray(list),
        material: Cesium.Color.fromCssColorString(color).withAlpha(fillop),
        fill: true,
        outline: true, // 是否显示 边框
        outlineWidth: sw, // 边框宽度
        outlineColor: Cesium.Color.fromCssColorString(color).withAlpha(sop), // 边框颜色
        zIndex: 20,
      },
    })

    example.push(tt)
  }

  /**
   * @description: 开启设备
   * @param {*} obj
   * @param {*} item
   */
  const openEquipment = async (obj, item) => {
    const res = await insertDisposalByDevice(obj)
    if (res.code === 200) {
      message({
        showClose: true,
        message: '指令下发成功',
        type: 'success',
      })
      drawDeviceAnimation(item)
    }
  }
  /**
   * @description: 关闭设备
   * @param {*} item 设备信息
   */
  const closeEquipmentCounter = async (item) => {
    let obj = {
      deviceId: item.id,
      strikeSeconds: 60,
      cityId: 28670,
      strikeType: item.disposalType,
      strikeCircuit: 2,
    }
    let res = await getcallDevice(obj)
    if (res.code == 200 || res.code == 201) {
      ElMessage.success(res.msg)
      //清除对应动画
      if (item.deviceType == 5) {
        //定向
        if (sectortimer) {
          clearInterval(sectortimer)
        }
        if (sectorarr.length > 0) {
          sectorarr.map((item) => {
            viewer.entities.remove(item)
          })
          sectorarr = []

          clearInterval(DraworientationIntval)
          DraworientationIntval = setInterval(() => {
            //绘制定向扇形
            Draworientation()
          }, 7000)
        }
      } else if (item.deviceType == 4) {
        //全向
        // console.log('zhixing')
        circleWaveList.forEach((item) => {
          viewer.entities.remove(item)
        })
      }
      // 清除对应定时器
      if (deviceCount[item.id].timer != null) {
        clearInterval(deviceCount[item.id].timer)
        deviceCount[item.id].timer = null
        delete deviceCount[item.id].timer
      }
      deviceCount[item.id].count = 60
      deviceCount[item.id].countdown = true
      deviceCount[item.id].counterType = ''
    }
  }
  /**
   * @description: 设备下发命令时 开启动画
   * @param {*} item 设备信息
   * @param {*} false 是否关闭动画
   */
  let sectortimer = null
  let deviceCount = {}
  let sectorarr = []
  const drawDeviceAnimation = (item, flag = false) => {
    // console.log('item', item)
    if (item.deviceType == 5) {
      //定向设备
      // 删除定向设备对应扇形
      if (orientationSector.length > 0) {
        clearInterval(DraworientationIntval)
        orientationSector.map((item) => {
          viewer.entities.remove(item)
        })
        orientationSector = []
      }
      let radius = 10
      let sop = 0.5 // 图形的边框颜色透明度
      // let sw = 8; // 图形的边框大小
      let sw = 1 // 图形的边框大小
      let fillop = 0.5 // 图形的填充颜色
      let i = 0
      let sectorAngle = item.includedAngle ? item.includedAngle : 120
      if (sectortimer != null) {
        clearInterval(sectortimer)
        sectortimer = null
      }

      sectortimer = setInterval(() => {
        let angle
        getdeviceAngle({
          deviceIds: [
            {
              deviceId: item.id,
            },
          ],
        }).then(({ data }) => {
          //扇形夹角
          sectorAngle = data[0].includedAngle ? data[0].includedAngle : 120
          angle = data[0].horizontal_angle - sectorAngle / 2
        })
        drawFanBorder(
          Number(item.deviceLongitude),
          Number(item.deviceLatitude),
          60,
          sectorAngle,
          radius,
          sectorarr,
          '#c1bd68',
          fillop,
          sw,
          sop
        )
        radius += 180
        fillop -= 0.05
        i = i + 1
        if (i == 10) {
          radius = 10
          i = 0
          fillop = 0.5
          sectorarr.map((item) => {
            viewer.entities.remove(item)
          })
          sectorarr = []
        }
      }, 500)

      deviceCount[item.id].count = 60
      deviceCount[item.id].countdown = false //倒计时
      deviceCount[item.id].counterType = item.counterType ? item.counterType : '' // 反制类型

      // 清除对应 旧 定时器
      if (deviceCount[item.id].timer != null) {
        clearInterval(deviceCount[item.id].timer)
        deviceCount[item.id].timer = null
        delete deviceCount[item.id].timer
      }
      // 开启对应 新 定时器
      deviceCount[item.id].timer = setInterval(() => {
        // 倒计时
        deviceCount[item.id].count-- //递减

        // 倒计时归零
        if (deviceCount[item.id].count <= 0) {
          // <=0 变成获取按钮
          deviceCount[item.id].countdown = true
          deviceCount[item.id].counterType = ''
          clearInterval(sectortimer)
          sectorarr.map((item) => {
            viewer.entities.remove(item)
          })
          sectorarr = []
          clearInterval(DraworientationIntval)
          DraworientationIntval = setInterval(() => {
            //绘制定向扇形
            Draworientation()
          }, 7000)
          // 清除对应定时器
          if (deviceCount[item.id].timer != null) {
            clearInterval(deviceCount[item.id].timer)
            deviceCount[item.id].timer = null
            delete deviceCount[item.id].timer
          }
          // 绘制 反制设备 威力范围
          // drawOrientantionSector(1)
        }
      }, 1000) //1000毫秒后执行
    } else {
      //全向设备
      // 开启动画
      // console.log('zhixing')
      circleWave(Number(item.deviceLongitude), Number(item.deviceLatitude))
      deviceCount[item.id].count = 60
      deviceCount[item.id].countdown = false //倒计时
      deviceCount[item.id].counterType = item.counterType ? item.counterType : '' // 反制类型

      // 开启对应 新 定时器
      deviceCount[item.id].timer = setInterval(() => {
        deviceCount[item.id].count-- //递减
        // 倒计时归零
        if (deviceCount[item.id].count <= 0) {
          // <=0 变成获取按钮
          deviceCount[item.id].countdown = true
          deviceCount[item.id].counterType = ''
          circleWaveList.forEach((item) => {
            viewer.entities.remove(item)
          })
          // 清除对应定时器
          if (deviceCount[item.id].timer != null) {
            clearInterval(deviceCount[item.id].timer)
            deviceCount[item.id].timer = null
            deviceCount[item.id].count = 60
          }
        }
      }, 1000) //1000毫秒后执行
    }
  }

  /**
   * @description: 历史点击数据
   * @param {*} item
   * @param {*} type 是否是从历史记录过来的
   */
  let flyTrackData = []
  const popuType = ref('')
  const historydata = async (item, type) => {
    if (showTrajectory == 1) {
      offDroneDetail()
    }
    showwhitelistdialog.value = false
    coverageShow.value = false
    showdeviceDetail.value = false
    showTrajectory = 1
    const result = await comdetail({
      batchNum: item.batchNo,
      intrusionStartTime: item.code,
      takeOffTime: item.takeoffTime,
    })
    if (result && result.droneCoors?.length > 0) {
      // 飞行轨迹最后一个点位信息
      let lastInfo = result.droneCoors[result.droneCoors.length - 1]

      // 飞行轨迹
      let list = result.droneCoors.map((item) => {
        // return [item.longitude * 1, item.latitude * 1, item.height * 1]
        return [item.gpsLongitude * 1, item.gpsLatitude * 1, 0]
      })

      item.batchNum = item.batchNo
      item.curSpeed = lastInfo.speed
      item.curHeight = lastInfo.height
      item.curFrequency = lastInfo.frequency
      item.curLongitude = lastInfo.gpsLongitude
      item.curLatitude = lastInfo.gpsLatitude
      item.direction = lastInfo.direction
      item.distance = lastInfo.distance
      item.driverLongitude = result.driverLongitude
      item.driverLatitude = result.driverLatitude

      // 是aoa设备
      if (result.aoaDevId && result.type == 2) {
        const { data } = await getDeviceLoc(result.aoaDevId)
        // 绘制aoa设备扇形角度
        if (flyTrackData.length > 0) {
          removeView(flyTrackData)
          flyTrackData = []
        }
        // 调整轨迹展示的视角
        let centeropt = {}
        viewer.camera.flyTo({
          destination: Cesium.Cartesian3.fromDegrees(
            Number(data.gpsLongitude),
            Number(data.gpsLatitude),
            7000
          ), //经度、纬度、高度
          orientation: {
            heading: Cesium.Math.toRadians(centeropt.heading || 0), //绕垂直于地心的轴旋转
            pitch: Cesium.Math.toRadians(-90), //绕纬度线旋转
            roll: Cesium.Math.toRadians(centeropt.roll || 0), //绕经度线旋转
          },
          duration: 3,
        })
        console.log('zhixing')
        console.log()
        //绘制aoa雷达
        drawRadar({
          lon: Number(data.gpsLongitude),
          lat: Number(data.gpsLatitude),
        })
        let angle = bearing(
          {
            longitude: data.gpsLongitude,
            latitude: data.gpsLatitude,
          },
          {
            longitude: Number(lastInfo.gpsLongitude),
            latitude: Number(lastInfo.gpsLatitude),
          }
        )
        angle = Number(angle)
        angle = angle < 0 ? 360 + angle : angle
        drawSector(
          data.gpsLongitude,
          data.gpsLatitude,
          angle,
          7.5,
          3000,
          flyTrackData,
          'rgba(221,70,88,0.5)'
        )
        // drawSector(
        //   Number(data.longitude),
        //   Number(data.latitude),
        //   0,
        //   lastInfo.direction == null ? 90 : lastInfo.direction,
        //   lastInfo.distance || 3000,
        //   flyTrackData,
        //   'rgba(255, 238, 111,0.1)',
        //   data
        // )
        let driverItem = {
          ...result,
          longitude: lastInfo.gpsLongitude,
          latitude: lastInfo.gpsLatitude,
          icon: '/img/icon-drone-end.png',
        }
        let driverMarker = drawMarker([driverItem])
        flyTrackData.push(...driverMarker)
        showDroneDetail(item, 2)
      } else {
        let iconUrl = 'heifei'
        if (item.type == 1 || item.type == 2) {
          /* 黑飞无人机 */
          iconUrl = 'heifei'
        } else if (item.type == 3) {
          if (item.policeDrone !== 1) {
            /* 白名单无人机 */
            iconUrl = 'baiminwu'
          } else {
            /* 警用无人机 */
            iconUrl = 'police'
          }
        } else if (item.type == 4) {
          /* 行业无人机 */
          iconUrl = 'trade'
        } else if (item.type == 7) {
          /* 民航 */
          iconUrl = 'minghang'
        }
        let data = {
          isTrack: true,
          list,
          speed: 1000,
          droneIcon: `/img/${iconUrl}.png`,
          driverIcon: '/img/icon-drone-start.png',
          color: '#f00',
          type: item.type,
        }
        const { driverPoint, line, entToStartLine, entitydd } = drawFlyTrack(data)
        flyTrackData.push(driverPoint, line, entToStartLine, entitydd)
        // drawHistoricalTrack(list, result.data.type, result.data.policeDrone, result.data.aoaDevId)
        showDroneDetail(item, 2)
      }
    }
    if (type) {
      popuType.value = type
    }
  }
  /**
   * @description: 绘制历史轨迹
   * @param {*} list 历史数据
   */
  const drawHistoricalTrack = (dataArr, type, policeDrone, aoaDevId = null) => {
    if (realtimeList_drone.length != 0) {
      removeView(realtimeList_drone)
      realtimeList_drone = []
    }
    clearHistorInfo()
    let droneType = type
    if (dataArr != null && dataArr.length > 0) {
      let arr = []
      let arrhist = []
      dataArr.map((it) => {
        arr.push([Number(it.longitude), Number(it.latitude)])
      })
      let iconUrl = 'heifei'
      if (type == 1 || type == 2) {
        /* 黑飞无人机 */
        iconUrl = 'heifei'
      } else if (type == 3) {
        if (policeDrone !== 1) {
          /* 白名单无人机 */
          iconUrl = 'baiminwu'
        } else {
          /* 警用无人机 */
          iconUrl = 'police'
        }
      } else if (type == 4) {
        /* 行业无人机 */
        iconUrl = 'trade'
      }
      //起点终点
      if (droneType != 2) {
        var historystrMarker = new Cesium.Entity({
          name: 'point',
          position: Cesium.Cartesian3.fromDegrees(
            Number(dataArr[0].longitude),
            Number(dataArr[0].latitude),
            dataArr[0].height || 0
          ),
          label: 'historystrMarker',
          billboard: {
            //这里需要改成您本地的路径的图片信息。
            image: require('/img/icon-drone-start'),
            height: 42,
            width: 42,
            disableDepthTestDistance: Number.POSITIVE_INFINITY,
          },
          cursorHand: true,
          pointPosition: [Number(dataArr[0].longitude), Number(dataArr[0].latitude)],
        })
        // historyendMarker = new AMap.Marker({
        //   map: aMap,
        //   position: new AMap.LngLat(
        //     dataArr[dataArr.length - 1].longitude,
        //     dataArr[dataArr.length - 1].latitude
        //   ),
        //   icon: new AMap.Icon({
        //     size: new AMap.Size(42, 42), // 图标尺寸
        //     image: require(`/img/${iconUrl}`),
        //     imageSize: new AMap.Size(42, 42),
        //   }),
        //   offset: new AMap.Pixel(-15, -15),
        // })
        historyendMarker = new Cesium.Entity({
          name: 'point',
          position: Cesium.Cartesian3.fromDegrees(
            Number(dataArr[dataArr.length - 1].longitude),
            Number(dataArr[dataArr.length - 1].latitude),
            dataArr[dataArr.length - 1].height || 0
          ),
          label: 'historystrMarker',
          billboard: {
            //这里需要改成您本地的路径的图片信息。
            image: require(`/img/${iconUrl}`),
            height: 42,
            width: 42,
            disableDepthTestDistance: Number.POSITIVE_INFINITY,
          },
          cursorHand: true,
          pointPosition: [
            Number(dataArr[dataArr.length - 1].longitude),
            Number(dataArr[dataArr.length - 1].latitude),
          ],
        })
        hisstrdata_markers.push(historystrMarker)
        hisstrdata_markers.push(historyendMarker)
        // var history_line = new AMap.Polyline({
        //   path: arr,
        //   strokeWeight: 4, // 线条宽度，默认为 1
        //   strokeColor: '#ff7800', // 线条颜色
        //   strokeOpacity: 1, // 线条透明度
        //   lineJoin: 'round', // 折线拐点连接处样式
        // })
        // aMap.add(history_line)
        var history_line = new Cesium.Entity({
          name: 'line',
          show: true,
          polylineVolume: {
            positions: Cesium.Cartesian3.fromDegreesArrayHeights(arr),
            shape: computeCircle(5.0),
            material: Cesium.Color.fromCssColorString(0xff7800).withAlpha(1),
            width: 4,
          },
          zIndex: 200,
          EntityType: 'polycodeline',
          cursorHand: true,
        })
        viewer.entities.add(history_line)
        historycode_line.push(history_line)

        // AMap.plugin('AMap.MoveAnimation', () => {
        //   // 线动画
        //   if (arr.length > 3) {
        //     historyendMarker.moveAlong(arr, {
        //       // 每一段的时长
        //       duration: 200, //可根据实际采集时间间隔设置
        //       // JSAPI2.0 是否延道路自动设置角度在 moveAlong 里设置
        //       //   autoRotation: false,
        //     })
        //   }
        // })
        arrhist.push(
          [dataArr[0].longitude, dataArr[0].latitude, 0],
          [dataArr[dataArr.length - 1].longitude, dataArr[dataArr.length - 1].latitude, 0]
        )
        // var history_doshline = new AMap.Polyline({
        //   path: arrhist,
        //   strokeWeight: 3, // 线条宽度，默认为 1
        //   strokeColor: 'skyblue', // 线条颜色
        //   strokeStyle: 'dashed',
        //   strokeOpacity: 1, // 线条透明度
        //   lineJoin: 'round', // 折线拐点连接处样式
        // })
        // aMap.add(history_doshline)

        var history_doshline = new Cesium.Entity({
          polyline: {
            positions: Cesium.Cartesian3.fromDegreesArrayHeights([...arrhist]),
            // 宽度
            width: 3,
            material: new Cesium.PolylineDashMaterialProperty({
              // 虚线
              color: Cesium.Color.fromCssColorString('skyblue'),
            }),
            show: true, // 是否显示
            clampToGround: true, // 开启贴地
          },
        })
        viewer.entities.add(history_doshline)
        historycode_line.push(history_doshline)
      } else if (droneType == 2) {
        historyendMarker = new Cesium.Entity({
          name: 'point',
          position: Cesium.Cartesian3.fromDegrees(
            Number(dataArr[dataArr.length - 1].longitude),
            Number(dataArr[dataArr.length - 1].latitude),
            dataArr[dataArr.length - 1].height || 0
          ),
          label: 'historyendMarker',
          billboard: {
            //这里需要改成您本地的路径的图片信息。
            image: require(`/img/icon-drone-end`),
            height: 42,
            width: 42,
            disableDepthTestDistance: Number.POSITIVE_INFINITY,
          },
          cursorHand: true,
          pointPosition: [
            Number(dataArr[dataArr.length - 1].longitude),
            Number(dataArr[dataArr.length - 1].latitude),
          ],
        })
        hisstrdata_markers.push(historyendMarker)
        // AOA 设备 侦测数据 开启雷达效果 绘制扇形
        let AOACenter = { lon: '', lat: '' }
        let newDroneInfo = dataArr[dataArr.length - 1]
        // this.AOAInfoList.map((x) => {
        //   if (x.id == aoaDevId) {
        //     AOACenter.lon = Number(x.longitude);
        //     AOACenter.lat = Number(x.latitude);
        //   }
        // });
        getDeviceLoc(aoaDevId).then((res) => {
          AOACenter = {
            lon: res.data.gpsLongitude,
            lat: res.data.gpsLatitude,
          }
          drawSector(
            res.data.gpsLongitude,
            res.data.gpsLatitude,
            lastInfo.direction == null ? 90 : lastInfo.direction,
            7.5,
            lastInfo.distance || 3000,
            flyTrackData,
            'rgba(221,70,88,0.5)'
          )
          let angle = bearing(
            {
              longitude: AOACenter.lon,
              latitude: AOACenter.lat,
            },
            {
              longitude: Number(newDroneInfo.longitude),
              latitude: Number(newDroneInfo.latitude),
            }
          )
          angle = Number(angle) - 10
          angle = angle < 0 ? 360 + angle : angle
          // drawDeviceCircles(AOACenter.lon, AOACenter.lat, angle, 20, 5000, AOAsector, 'red')
          // let aoaDataMarket = [];
          let aoaIndexof = arrEqument.some((animal) => animal.deviceId === res.data.deviceId)
          if (aoaIndexof == false) {
            aoadrawPoint(res.data)
          }
        })
      }
    }
  }

  /**
   * @description: 地图上图标的点击事件
   */
  let markersArr = []
  const handlePointClick = () => {
    let handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas)
    handler.setInputAction(function (click) {
      let pick = viewer.scene.pick(click.position)
      if (pick && pick.id.name) {
        let { info } = pick.id
        if (
          [
            'directional',
            'omnidirectional',
            'photoelectricity',
            'decoding',
            'radar',
            'aoa',
            'adsb',
          ].includes(pick.id.name)
        ) {
          if (showTrajectory == 1) {
            offDroneDetail(false)
          }
          deviceInfo.value = info
          if (showdeviceDetail.value == false) {
            // 调整轨迹展示的视角
            let centeropt = {}
            viewer.camera.flyTo({
              destination: Cesium.Cartesian3.fromDegrees(...carPositon, centeropt.z || 7000), //经度、纬度、高度
              orientation: {
                heading: Cesium.Math.toRadians(centeropt.heading || 0), //绕垂直于地心的轴旋转
                pitch: Cesium.Math.toRadians(-90), //绕纬度线旋转
                roll: Cesium.Math.toRadians(centeropt.roll || 0), //绕经度线旋转
              },
              duration: 3,
            })
          }
          showdeviceDetail.value = true
        }
      }
      if (pick && pick.id.name == 'car') {
        // 调整轨迹展示的视角
        let centeropt = {}
        viewer.camera.flyTo({
          destination: Cesium.Cartesian3.fromDegrees(...carPositon, centeropt.z || 7000), //经度、纬度、高度
          orientation: {
            heading: Cesium.Math.toRadians(centeropt.heading || 0), //绕垂直于地心的轴旋转
            pitch: Cesium.Math.toRadians(-90), //绕纬度线旋转
            roll: Cesium.Math.toRadians(centeropt.roll || 0), //绕经度线旋转
          },
          duration: 3,
        })
      }
      if (pick && pick.id) {
        viewer.entities.values.map((item) => {
          // 点击无人机
          if (pick.id.batchNo && item.batchNo == pick.id.batchNo) {
            let data = pick.id.data
            showDroneDetail(data, 1)
          }
        })
      }
      //点击定向设备
      if (deviceDetail.value?.modeltype == '2') {
        let nowPosition = getLonOrLat(click.position)
        let lanlatArr = [Number(nowPosition.longitude), Number(nowPosition.latitude), 0]
        if (markersArr.length > 0) {
          // console.log(markersArr[0])
          markersArr[0].position = Cesium.Cartesian3.fromDegrees(...lanlatArr)
        } else {
          let markerPoint = new Cesium.Entity({
            name: 'markerPoint',
            show: true,
            position: Cesium.Cartesian3.fromDegrees(...lanlatArr),
            billboard: {
              //这里需要改成您本地的路径的图片信息。
              image: '/img/marker.png',
              height: 30,
              width: 30,
              disableDepthTestDistance: Number.POSITIVE_INFINITY,
            },
          })
          viewer.entities.add(markerPoint)
          markersArr.push(markerPoint)
        }
        deviceDetail.value.sendLngLat(nowPosition)
      }
    }, Cesium.ScreenSpaceEventType.LEFT_CLICK)
    viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(
      Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK
    ) //去除双击放大地图效果
    // 创建一个tooltip元素
    const tooltip = document.createElement('div')
    tooltip.style.position = 'absolute'
    tooltip.style.padding = '4px'
    tooltip.style.background = '#181818'
    tooltip.style.color = 'white'
    tooltip.style.borderRadius = '4px'
    tooltip.style.display = 'none'
    document.body.appendChild(tooltip)
    handler.setInputAction(function (movement) {
      const pick = viewer.scene.pick(movement.endPosition)
      if (Cesium.defined(pick) && pick.id.name) {
        if (
          [
            'directional',
            'omnidirectional',
            'photoelectricity',
            'decoding',
            'radar',
            'aoa',
            'adsb',
          ].includes(pick.id.name)
        ) {
          tooltip.style.display = 'block'
          let str =
            pick.id.name == 'directional'
              ? '定向反制设备'
              : pick.id.name == 'omnidirectional'
              ? '全向反制设备'
              : pick.id.name == 'decoding'
              ? '解码侦测设备'
              : pick.id.name == 'radar'
              ? '雷达侦测设备'
              : pick.id.name == 'aoa'
              ? 'AOA侦测设备'
              : pick.id.name == 'adsb'
              ? 'ADS-B侦测设备'
              : ''
          tooltip.innerHTML = str
          tooltip.style.left = movement.endPosition.x + 10 + 'px'
          tooltip.style.top = movement.endPosition.y + 10 + 'px'
        }
      } else {
        tooltip.style.display = 'none'
      }
    }, Cesium.ScreenSpaceEventType.MOUSE_MOVE)
  }

  /**
   * @description: 清除定向设备选择朝向的标识点
   */
  const cancelMarker = () => {
    if (markersArr.length > 0) {
      removeView(markersArr)
      markersArr = []
    }
  }

  /**
   * @description: 经纬度转换
   */
  const getLonOrLat = (cartesian2) => {
    var cartesian = viewer.scene.globe.pick(viewer.camera.getPickRay(cartesian2), viewer.scene)
    // console.log('cartesian',cartesian);
    let cartorgraphic = Cesium.Cartographic.fromCartesian(cartesian)
    // console.log('ddd', cartorgraphic);
    let lon = Cesium.Math.toDegrees(cartorgraphic.longitude) // 经度
    let lat = Cesium.Math.toDegrees(cartorgraphic.latitude) // 纬度
    // console.log(`经度：${lon},纬度:${lat}`);
    return {
      longitude: lon,
      latitude: lat,
    }
  }

  /**
   * @description: 隐藏无人机轨迹弹窗
   */
  let showTrajectory = 0 // 是否显示轨迹 0否1是
  let drawState = null // 绘制无人机轨迹
  let droneKey = null
  let beforeDroneList = [] // 接口返回当前无人机数据
  const offDroneDetail = (flag = true) => {
    let dom = document.querySelector('.detail-box')
    dom.style.display = 'none' //隐藏弹窗
    // 关闭弹窗
    // inversecheckbox(dom)
    // showMask.value = false
    //清除logo标识
    droneActiveId.value = null
    if (flag) {
      defaultAngle()
    }
    clearHistorInfo()
    clearRealTimeInfo()
    clearaoaPoint()
    drawState = null
    droneKey = null
    beforeDroneList = []
    showTrajectory = 0
    // 清除轨迹播放的相关图标、航线
    if (flyTrackData.length > 0) {
      removeView(flyTrackData)
      flyTrackData = []
    }

    if (aoaSectorArr.length > 0) {
      removeView(aoaSectorArr)
      aoaSectorArr = []
    }

    if (flystrdata_markers.length > 0) {
      removeView(flystrdata_markers)
      flystrdata_markers = []
    }
    getRealTimeList() //获取在飞列表
    if (popuType.value == 'history') {
      selectNav.value = 'historical'
      historyShow.value = true
      showwhitelistdialog.value = false
      defenseShow.value = false
      popuType.value = ''
      enableTool(false)
    }
  }
  /**
   * @description: 关闭所有弹窗
   */
  const closealldialog = () => {
    if (showTrajectory == 1) {
      offDroneDetail()
    }
    showdeviceDetail.value = false
  }

  /**
   * @description: 显示无人机轨迹
   * @param {*} item 无人机数据
   * @param {*} type 类型  1 实时 2 历史
   */
  const droneActiveId = ref(null)
  const showDroneDetail = (item, type) => {
    showwhitelistdialog.value = false
    coverageShow.value = false
    showdeviceDetail.value = false
    // 播放轨迹前清除无人机图标
    removeView(realtimeList_drone)
    realtimeList_drone = []
    beforeDroneList = []
    droneActiveId.value =
      item.code +
      (item.batchNo || item.batchNum) +
      dayjs(item.takeoffTime).format('YYYY-MM-DD HH:mm:ss')
    // if (showDronePopup.value === 'disposal') {
    //   //关闭处置舍设备列表
    //   // offDisposalList()
    // } else if (showDronePopup.value == 'equipmentDetail') {
    //   //开启或者关闭设备
    //   showDeviceInfo(2)
    // }
    if (type == 1) {
      clearRealTimeInfo()
      clearHistorInfo()
      item.direction = item.curDirection
      item.distance = item.curDistance
      drawRealTimeRajectory(item.droneCode, item.droneKey, item, type)
    }
    if (type == 2 && item.power) {
      delete item.power
    }
    let data = {
      showType: type,
      droneID: item.batchNum,
      droneModel: item.model,
      departureTime: dayjs(item.takeoffTime).format('YYYY-MM-DD HH:mm:ss'),
      flyingLon: item.driverLongitude,
      flyingLat: item.driverLatitude,
      spectrum: item.curFrequency,
      curLon: item.curLongitude,
      curLat: item.curLatitude,
      height: item.curHeight,
      speed: item.curSpeed,
      info: item,
      type: item.type,
    }
    showDronePopup.value = 'droneDetail'
    let dom = document.querySelector('.detail-box')
    // 开启弹窗
    checkbox(dom)
    setTimeout(() => {
      if (type == 2) {
        droneInfo.value = data
      }
    }, 500)
  }

  /**
   * @description: 清除实时数据 点 轨迹
   */
  let flystrdata_markers = []

  const clearRealTimeInfo = () => {
    if (flystrdata_markers.length > 0) {
      removeView(flystrdata_markers)
      flystrdata_markers = []
    }
    if (addPolycodeline && addPolycodeline.length > 0) {
      removeView(addPolycodeline)
      addPolycodeline = []
    }
    if (AOARadarList.length > 0) {
      removeView(AOARadarList)

      AOARadarList = []
    }
    if (AOAsector.length > 0) {
      removeView(AOAsector)
      AOAsector = []
    }
    if (flyTrackData.length > 0) {
      removeView(flyTrackData)
      flyTrackData = []
    }
    if (aoaSectorArr.length > 0) {
      removeView(aoaSectorArr)
      aoaSectorArr = []
    }
  }
  /**
   * @description: 清除历史数据 点 轨迹
   */
  let AOAsector = [] // 存放AOA 设备扇形区域
  let historyendMarker = null // 历史轨迹无人机图标
  let hisstrdata_markers = [] // 无人机轨迹 图标数据
  let historycode_line = [] //  无人机轨迹 线数据
  let AOARadarList = [] // 绘制 AOA 设备 雷达效果
  const clearHistorInfo = () => {
    if (historyendMarker != null) {
      // historyendMarker.stopMove()
      historyendMarker = null
    }
    if (hisstrdata_markers != null && hisstrdata_markers.length > 0) {
      removeView(hisstrdata_markers)

      hisstrdata_markers = []
    }

    if (historycode_line && historycode_line.length > 0) {
      removeView(historycode_line)

      historycode_line = []
    }
    if (AOARadarList.length > 0) {
      removeView(AOARadarList)

      AOARadarList = []
    }
    if (AOAsector.length > 0) {
      removeView(AOAsector)

      AOAsector = []
    }
  }
  /**
   * @description: 开启弹窗
   * @param {*} dom 弹窗的节点
   * @param {*} Name 弹出的动画类名
   */
  let isani = ref(true)
  const checkbox = (dom, Name) => {
    setTimeout(() => {
      isani.value = true
      dom && (dom.style.display = 'block')
      //显示弹窗
    })
    // setTimeout(() => {
    //   isani.value = true
    // })
  }
  /**
   * @description: 清除其他aoa设备
   */
  let aoadraw_markers = [] //绘制其他aoa设备图标
  const clearaoaPoint = () => {
    if (aoadraw_markers != null && aoadraw_markers.length > 0) {
      aoadraw_markers.forEach((s) => {
        aMap.remove(s)
      })
      aoadraw_markers = []
    }
  }
  /**
   * @cesium画扇形
   * @description position 坐标
   * @description axisAngle 扇形中心线的北偏角
   * @description sectorAngle 扇形角度
   * @description radius 扇形半径
   */
  const drawSector = (
    longitude,
    latitude,
    axisAngle,
    sectorAngle = 60,
    radius,
    example,
    color = '#60a0bf',
    special = null
  ) => {
    let position = [Number(longitude), Number(latitude)]
    var headings = Cesium.Math.toRadians(axisAngle - 90)
    let ellipsoid = new Cesium.Entity({
      name: '扇形',
      position: Cesium.Cartesian3.fromDegrees(...position),
      orientation: Cesium.Transforms.headingPitchRollQuaternion(
        Cesium.Cartesian3.fromDegrees(...position),
        new Cesium.HeadingPitchRoll(headings, 0, 0)
      ),
      ellipsoid: {
        radii: new Cesium.Cartesian3(radius, radius, radius), // 扇形半径
        innerRadii: new Cesium.Cartesian3(1.0, 1.0, 1.0), // 内半径
        minimumClock: Cesium.Math.toRadians(-sectorAngle / 2), // 左右偏角
        maximumClock: Cesium.Math.toRadians(sectorAngle / 2),
        minimumCone: Cesium.Math.toRadians(90), // 上下偏角  可以都设置为90
        maximumCone: Cesium.Math.toRadians(90),
        material: Cesium.Color.fromCssColorString(color).withAlpha(0.3),
        outline: false,
      },
    })
    example.push(ellipsoid)
    viewer.entities.add(ellipsoid)
    return ellipsoid
  }

  /**
   * @description：cesium绘制实时飞行轨迹
   */
  let lastRealTime = []
  const drawFlyRealTimeTrack = (data) => {
    console.log('data', data)
    let len = data.list.length
    // if (lastRealTime.length > 0 && lastRealTime[0] == data.list[len - 1][0] && lastRealTime[1] == data.list[len - 1][1]) {
    //   console.log('出现重复数据');
    //   return
    // }

    if (flyTrackData.length > 0) {
      removeView(flyTrackData)
      flyTrackData = []
    }
    // 轨迹路线
    // console.log('轨迹数据----------------')
    let line = null
    if (data.type != 7 && data.type != 1) {
      line = new Cesium.Entity({
        name: 'line',
        show: true,
        polyline: {
          positions: Cesium.Cartesian3.fromDegreesArrayHeights([...data.list.flat()]),
          width: 1.0,
          material: Cesium.Color.fromCssColorString(data.color).withAlpha(1),
        },
        zIndex: 200,
        cursorHand: true,
      })
    } else {
      line = null
    }
    // 飞手
    let driverPoint = null
    if (data.type != 7 && data.type != 1) {
      console.log('data.type != 1', data.type != 1)
      driverPoint = new Cesium.Entity({
        name: 'point',
        show: true,
        position: Cesium.Cartesian3.fromDegrees(...data.list[0]),
        billboard: {
          //这里需要改成您本地的路径的图片信息。
          image: data.driverIcon,
          height: 47,
          width: 42,
          disableDepthTestDistance: Number.POSITIVE_INFINITY,
        },
      })
    } else {
      driverPoint = null
    }
    //无人机
    let dronePoint = null
    dronePoint = new Cesium.Entity({
      name: 'point',
      show: true,
      position: Cesium.Cartesian3.fromDegrees(...data.list[len - 1]),
      billboard: {
        //这里需要改成您本地的路径的图片信息。
        image: data.droneIcon,
        height: 40,
        width: 40,
        disableDepthTestDistance: Number.POSITIVE_INFINITY,
      },
    })
    lastRealTime = [...data.list[len - 1]]
    if (data.type != 7 && data.type != 1) {
      viewer.entities.add(driverPoint)
    }
    viewer.entities.add(dronePoint)
    if (data.type != 7 && data.type != 1) {
      viewer.entities.add(line)
    }
    return { driverPoint, line, dronePoint }
  }

  /*
   * 计算民航飞机方向角
   * */
  const calculateBearing = (lon1, lat1, lon2, lat2) => {
    const lat1Rad = (lat1 * Math.PI) / 180
    const lat2Rad = (lat2 * Math.PI) / 180
    const dLon = ((lon2 - lon1) * Math.PI) / 180

    const y = Math.sin(dLon) * Math.cos(lat2Rad)
    const x =
      Math.cos(lat1Rad) * Math.sin(lat2Rad) - Math.sin(lat1Rad) * Math.cos(lat2Rad) * Math.cos(dLon)

    let bearing = (Math.atan2(y, x) * 180) / Math.PI
    bearing = (bearing + 360) % 360

    return bearing
  }
  /**
   * @description：cesium绘制历史飞行轨迹
   */
  const drawFlyTrack = (data) => {
    if (flyTrackData.length > 0) {
      removeView(flyTrackData)
      flyTrackData = []
    }
    // 轨迹路线
    let line = new Cesium.Entity({
      name: 'line',
      show: true,
      polyline: {
        positions: Cesium.Cartesian3.fromDegreesArrayHeights([...data.list.flat()]),
        width: 1.0,
        material: Cesium.Color.fromCssColorString(data.color).withAlpha(1),
      },
      zIndex: 200,
      cursorHand: true,
    })
    let len = data.list.length
    let driverPoint
    // 飞手
    if (data.type != 7 && data.type != 1) {
      driverPoint = new Cesium.Entity({
        name: 'point',
        show: true,
        position: Cesium.Cartesian3.fromDegrees(...data.list[0]),
        billboard: {
          //这里需要改成您本地的路径的图片信息。
          image: data.driverIcon,
          height: 47,
          width: 42,
          disableDepthTestDistance: Number.POSITIVE_INFINITY,
        },
      })
    } else {
      driverPoint = null
    }
    // 飞手到航线起点连线
    let entToStartLine = new Cesium.Entity({
      name: 'line',
      show: true,
      polyline: {
        positions: Cesium.Cartesian3.fromDegreesArrayHeights([
          ...data.list[0],
          ...data.list[len - 1],
        ]),
        width: 2,
        material: new Cesium.PolylineDashMaterialProperty({
          color: Cesium.Color.fromCssColorString('#0ff').withAlpha(1),
          dashLength: 20, //短划线长度
        }),
      },
      disableDepthTestDistance: Number.POSITIVE_INFINITY,
    })
    viewer.entities.add(entToStartLine)
    if (data.type != 7 && data.type != 1) {
      viewer.entities.add(driverPoint)
    }
    viewer.entities.add(line)
    // 调整轨迹展示的视角
    let centeropt = {}
    viewer.camera.flyTo({
      destination: Cesium.Cartesian3.fromDegrees(
        data.list[0][0],
        data.list[0][1],
        centeropt.z || 7000
      ), //经度、纬度、高度
      orientation: {
        heading: Cesium.Math.toRadians(centeropt.heading || 0), //绕垂直于地心的轴旋转
        pitch: Cesium.Math.toRadians(-90), //绕纬度线旋转
        roll: Cesium.Math.toRadians(centeropt.roll || 0), //绕经度线旋转
      },
      duration: 3,
    })

    let entitydd = null
    // 无人机飞行轨迹
    if (data.isTrack) {
      let arr = []
      let property = new Cesium.SampledPositionProperty()
      let starttime = new Date()
      let stoptime
      let timestamp = starttime.getTime()
      let linePositions = data.list
      linePositions.forEach((item, index) => {
        arr.push(Number(item[0]), Number(item[1]), Number(item[2]))
        let time = new Date(timestamp + index * (data.speed || 5000))
        stoptime = time
        let position = Cesium.Cartesian3.fromDegrees(
          Number(item[0]),
          Number(item[1]),
          Number(item[2])
        )
        property.addSample(Cesium.JulianDate.fromDate(time), position)
      })
      property.setInterpolationOptions({
        interpolationDegree: 0.0001,
        interpolationAlgorithm: Cesium.LagrangePolynomialApproximation,
      })
      if (data.type == 7) {
        entitydd = new Cesium.Entity({
          availability: new Cesium.TimeIntervalCollection([
            new Cesium.TimeInterval({
              start: Cesium.JulianDate.fromDate(starttime),
              stop: Cesium.JulianDate.fromDate(new Date(stoptime)),
            }),
          ]),
          // 点集
          position: property,
          // 朝向
          orientation: new Cesium.VelocityOrientationProperty(property),
          // 模型
          model: {
            uri: '/3dTiles/model/minghang.glb', // 飞机模型
            scale: 0.5, // 模型轮廓大小
            minimumPixelSize: 70,
            maximumScale: 70,
          },
          viewFrom: new Cesium.Cartesian3(500, 500, 100), // 偏移量--设置视角高度
        })
      } else {
        entitydd = new Cesium.Entity({
          availability: new Cesium.TimeIntervalCollection([
            new Cesium.TimeInterval({
              start: Cesium.JulianDate.fromDate(starttime),
              stop: Cesium.JulianDate.fromDate(new Date(stoptime)),
            }),
          ]),
          // 点集
          position: property,
          // 朝向
          orientation: new Cesium.VelocityOrientationProperty(property),
          // 图片
          billboard: {
            image: data.droneIcon, // 图像地址，URI或Canvas的属性
            width: 40, // 宽度（以像素为单位）
            height: 40, // 高度（以像素为单位）
            verticalOrigin: Cesium.VerticalOrigin.CENTER, // 相对于坐标的垂直位置
            horizontalOrigin: Cesium.HorizontalOrigin.CENTER, // 相对于坐标的水平位置
            show: true, // 是否显示
            disableDepthTestDistance: Number.POSITIVE_INFINITY,
          },
          viewFrom: new Cesium.Cartesian3(500, 500, 100), // 偏移量--设置视角高度
        })
      }
      // viewer.trackedEntity = entitydd   // 视角跟随
      viewer.clock.currentTime = Cesium.JulianDate.fromDate(starttime) //修改时间轴的当前时间
      viewer.clock.stopTime = Cesium.JulianDate.fromDate(new Date(stoptime))
      viewer.clock.clockRange = Cesium.ClockRange.CLAMPED
      viewer.clock.shouldAnimate = true //开始播放
      viewer.entities.add(entitydd)
    }
    return { driverPoint, line, entToStartLine, entitydd }
  }
  /**
   * @description: 绘制围绕车的三级防御圈
   */
  const drawDenfens = (data) => {
    if (companyLayers.length > 0) {
      companyLayers.forEach((item) => {
        //更改防御圈中心点位置
        item.position = Cesium.Cartesian3.fromDegrees(data[0], data[1], 0)
      })
    } else {
      let params = {
        longitude: data[0],
        latitude: data[1],
      }
      let circleLists = [
        { limitFlyType: 1, radius: 1000 }, //核心圈
        { limitFlyType: 5, radius: 2000 }, //反制圈
        { limitFlyType: 10, radius: 3000 }, //警戒圈
      ]
      circleLists.forEach((item) => {
        params.limitFlyType = item.limitFlyType
        params.radius = item.radius
        drawCircle(params)
      })
    }
  }
  /**
   * @description: 回显三级防御圈
   */
  const mapCenterData = ref([])
  const waveRadius = ref(null)
  const getDenfensInfo = () => {
    //清除cesium 防御圈缓存
    if (companyLayers.length > 0) {
      removeView(companyLayers)
      companyLayers = []
    }
    getDefense().then((res) => {
      if (res.code * 1 == 200) {
        if (res.data.length > 0) {
          let infos = res.data[0].managementBoundaryInfos
          infos.map((item, index) => {
            if (item.shape == 1) {
              //绘制圆形
              drawPolygon(item, 'managementCoordinateTDOS')
            } else if (item.shape == 0) {
              //绘制圆形
              drawCircle(item)
              if (item.limitFlyType == 10) {
                mapCenterData.value = [Number(item.longitude), Number(item.latitude)]
                waveRadius.value = item.radius
              }
            }
          })
        }
        defaultAngle()
        //水波纹
        if (mapCenterData.value.length > 0) {
          // waveCircle(mapCenterData.value, waveRadius.value)
        }
      }
    })
  }
  /**
   * @description: 获取设备列表
   */
  const deviceList = ref([])

  const getDeviceData = () => {
    getDeviceList().then((res) => {
      deviceList.value = res.data
    })
  }
  onMounted(() => {
    initMap()
    window.addEventListener('resize', onWindowResize, false)
    getRealTimeList()
    hist_comdetect()
    handlePointClick()
    getDeviceData() //设备列表
    setTimeout(() => {
      drawCardevice()
      Draworientation()
      //默认视角
      setTimeout(() => {
        defaultAngle()
      }, 500)
    }, 500)
    clearInterval(DraworientationIntval)
    DraworientationIntval = setInterval(() => {
      //绘制定向扇形
      drawCardevice()
      Draworientation()
    }, 7000)
  })

  onUnmounted(() => {
    try {
      resMgr && resMgr.dispose()
      renderer.dispose()
      renderer.forceContextLoss()
      renderer.content = null
      cancelAnimationFrame(() => {
        requestId.value
      })
      renderer.domElement = null
      clearInterval(DraworientationIntval)
    } catch (e) {}
  })
</script>
<style lang="scss" scoped>
  @import './home.scss';
  .toolBox {
    width: 300px;
    position: absolute;
    bottom: 30px;
    right: 480px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    z-index: 2;
    .toolItem {
      width: 120px;
      height: 40px;
      font-family: PingFang SC;
      font-weight: bold;
      font-size: 16px;
      color: #ffffff;
      text-align: center;
      line-height: 40px;
      cursor: pointer;
      position: relative;
      .defense-list {
        position: absolute;
        bottom: 60px;
        width: 120px;
        .defense-item {
          background-color: #084570;
          height: 40px;
          font-size: 14px;
          color: #c3e5ff;
          line-height: 40px;
          padding-left: 3px;
        }
        .defense-item:hover {
          background-color: #2666a2;
          color: #ffffff;
          cursor: pointer;
        }
        .active-defense {
          background-color: #2666a2;
          color: #ffffff;
        }
      }
    }
    .toolItem:hover {
      transition: 0.5s;
      background: url('/img/active-tool.png') no-repeat;
    }
    .active-box {
      background: url('/img/active-tool.png') no-repeat;
    }
    .normal-box {
      background: url('/img/inactive-tool.png') no-repeat;
    }
  }
  .home-right {
    width: 20%;
    position: absolute;
    top: 8.6vh;
    right: 30px;
    z-index: 10;
    /* background: linear-gradient(90deg, rgba(0, 0, 0, 0.2), rgba(0, 0, 0, 0)); */
    padding-right: 0;
    height: calc(100% - 14vh);
    /* // 实时告警列表 */
    .real-time-box {
      position: relative;
      padding-top: 3%;
      padding-left: 3%;
      display: flex;
      flex-direction: column;
      color: #fff;
      font-size: 12px;
      height: calc(100% - 60px);
      line-height: 24px;
      width: calc(100% - 0px);
      overflow-y: auto;

      .empty {
        margin: auto;
        color: rgb(118, 129, 139);
      }

      .real-list {
        .real-list-item {
          display: flex;
          align-items: center;
          margin-bottom: 8px;
          height: 74px;
          margin: 0 0 14px;
          position: relative;

          // 单行文字超过隐藏
          .model {
            width: 45%;
            display: inline-block;
            overflow: hidden;
            white-space: nowrap;
            text-overflow: ellipsis;
          }

          &.active {
            .active-icon {
              visibility: visible;
            }
          }

          .active-icon {
            width: 20px;
            height: 20px;
            background: url('/img/arrow.png') no-repeat;
            transform: rotate(180deg);
            background-size: 100%;
            right: -24px;
            top: 50%;
            margin-top: 2%;
            visibility: hidden;
          }

          .info.active {
            .active-icon {
              display: inline-block;
            }
          }

          .info-detail-icon {
            display: inline-block;
            width: 20px;
            height: 20px;
            background: url('/img/his-details.png') no-repeat;
            background-size: 100%;
            position: absolute;
            right: 2px;
            bottom: 1px;
            cursor: pointer;
          }

          .info {
            width: 20vw;
            position: relative;
            padding: 2px 5px;

            &.gray {
              border: 1px solid rgba(156, 156, 156, 1);
              box-shadow: 0px 2px 3px 0px rgba(156, 156, 156, 1);
              border-radius: 4px;
              background: rgba(156, 156, 156, 0.5);
              height: 95%;
            }

            &.red {
              border: 1px solid rgba(238, 70, 70, 1);
              box-shadow: 0px 2px 3px 0px rgba(238, 70, 70, 1);
              border-radius: 4px;
              background: rgba(238, 70, 70, 0.5);
              height: 95%;
            }

            &.blue {
              border: 1px solid rgba(80, 196, 236, 1);
              box-shadow: 0px 2px 3px 0px rgba(80, 196, 236, 1);
              border-radius: 4px;
              background: rgba(80, 196, 236, 0.5);
              height: 95%;
            }

            &.orange {
              border: 1px solid rgba(255, 216, 99, 1);
              box-shadow: 0px 2px 3px 0px rgba(255, 216, 99, 1);
              border-radius: 4px;
              background: rgba(255, 216, 99, 0.5);
              height: 95%;
            }

            .info-top {
              width: 100%;
              display: flex;
              align-content: center;
              align-items: center;
              justify-content: space-between;

              img {
                width: 16px;
                height: 16px;
              }

              span {
                font-size: calc(100vw / 1920 * 12);
                font-family: Microsoft YaHei;
                font-weight: 400;
                color: #ffffff;
                // white-space: nowrap;
                overflow: hidden;
                text-overflow: ellipsis;
              }
            }

            .info-bottom {
              width: 90%;
              overflow: hidden;
              text-overflow: ellipsis;
              display: -webkit-box;
              -webkit-box-orient: vertical;
              -webkit-line-clamp: 2;
              word-break: break-all;
              line-height: 1.4;
              margin-top: 4px;

              .tip-btn {
                width: 100%;
                height: 24px;
                justify-content: flex-start;
              }
            }
          }
        }

        .real-list-item1 {
          display: flex;
          align-items: center;
          margin-bottom: 8px;
          height: 74px;
          margin: 0 0 14px;
          position: relative;

          // 单行文字超过隐藏
          .model {
            width: 45%;
            display: inline-block;
            overflow: hidden;
            white-space: nowrap;
            text-overflow: ellipsis;
          }

          &.active {
            .active-icon {
              visibility: visible;
            }
          }

          .active-icon {
            width: 20px;
            height: 20px;
            background: url('/img/arrow.png') no-repeat;
            transform: rotate(180deg);
            background-size: 100%;
            right: -24px;
            top: 50%;
            margin-top: 2%;
            visibility: hidden;
          }

          .info.active {
            .active-icon {
              display: inline-block;
            }
          }

          .info-detail-icon {
            display: inline-block;
            width: 20px;
            height: 20px;
            background: url('/img/his-details.png') no-repeat;
            background-size: 100%;
            position: absolute;
            right: 2px;
            bottom: 1px;
            cursor: pointer;
          }

          .info {
            width: 20vw;
            position: relative;
            padding: 2px 5px;

            &.gray {
              border: 1px solid rgba(156, 156, 156, 1);
              box-shadow: 0px 2px 3px 0px rgba(156, 156, 156, 1);
              border-radius: 4px;
              background: rgba(156, 156, 156, 0.5);
              height: 95%;
            }

            &.red {
              border: 1px solid rgba(238, 70, 70, 1);
              box-shadow: 0px 2px 3px 0px rgba(238, 70, 70, 1);
              border-radius: 4px;
              background: rgba(238, 70, 70, 0.5);
              height: 95%;
            }

            &.blue {
              border: 1px solid rgba(80, 196, 236, 1);
              box-shadow: 0px 2px 3px 0px rgba(80, 196, 236, 1);
              border-radius: 4px;
              background: rgba(80, 196, 236, 0.5);
              height: 95%;
            }

            &.orange {
              border: 1px solid rgba(255, 216, 99, 1);
              box-shadow: 0px 2px 3px 0px rgba(255, 216, 99, 1);
              border-radius: 4px;
              background: rgba(255, 216, 99, 0.5);
              height: 95%;
            }

            .info-top {
              width: 100%;
              display: flex;
              align-content: center;
              align-items: center;
              justify-content: space-between;

              img {
                width: 16px;
                height: 16px;
              }

              span {
                font-size: calc(100vw / 1920 * 12);
                font-family: Microsoft YaHei;
                font-weight: 400;
                color: #ffffff;
                // white-space: nowrap;
                overflow: hidden;
                text-overflow: ellipsis;
              }
            }

            .info-bottom {
              width: 90%;
              overflow: hidden;
              text-overflow: ellipsis;
              display: -webkit-box;
              -webkit-box-orient: vertical;
              -webkit-line-clamp: 2;
              word-break: break-all;
              line-height: 1.4;
              margin-top: 4px;

              .tip-btn {
                width: 100%;
                height: 24px;
                justify-content: flex-start;
              }
            }
          }
        }
      }
    }

    .real-time-box::-webkit-scrollbar {
      /* //去除滚动条 */
      display: none;
    }
    .real-time-box-overlay {
      position: absolute;
      bottom: 27%;
      left: 0;
      width: 100%;
      height: 100px;
      background: linear-gradient(
        to bottom,
        rgba(0, 0, 0, 0),
        rgba(0, 0, 0, 0.4)
      ); /* 使用线性渐变来设置遮罩的透明度渐变 */
      z-index: 10; /* 确保遮罩位于内容之上 */
      pointer-events: none; /* 让遮罩不拦截鼠标事件，使内容仍然可交互 */
    }
  }
</style>
